From: tsteven4 <13596209+tsteven4@users.noreply.github.com> Date: Thu, 15 Aug 2024 11:50:46 +0000 (-0600) Subject: update shapelib to 1.6.1 (#1323) X-Git-Tag: archive/raspbian/1.10.0+ds-2+rpi1~1^2~12^2^2~67 X-Git-Url: https://dgit.raspbian.org/%22http:/www.example.com/cgi/%22https://%22Program/%22http:/www.example.com/cgi/%22https:/%22Program?a=commitdiff_plain;h=e9b2084bc9338fe8b4ad709580cfc84dee283b2b;p=gpsbabel.git update shapelib to 1.6.1 (#1323) --- diff --git a/shapelib.cmake b/shapelib.cmake index d52f28e3c..7cd4b7b25 100644 --- a/shapelib.cmake +++ b/shapelib.cmake @@ -15,14 +15,19 @@ else() shapelib/safileio.c shapelib/shpopen.c shapelib/shapefil.h + shapelib/shapefil_private.h ) # note gpsbabel has conditional code include "shapelib/shapefil.h", # so it doesn't actually rely on the include directory being PUBLIC/INTERFACE target_include_directories(shp PUBLIC shape) + include(TestBigEndian) + if(HAVE_BYTE_ORDER_BIG_ENDIAN) + # Define SHP_BIG_ENDIAN if the system is big-endian + target_compile_definitions(shp PRIVATE SHP_BIG_ENDIAN=1) + endif() if(MSVC) target_compile_definitions(shp PRIVATE _CRT_SECURE_NO_WARNINGS) - target_compile_definitions(shp PRIVATE _CRT_NONSTDC_NO_WARNINGS) - target_compile_options(shp PRIVATE /MP -wd4100 -wd4267) + target_compile_options(shp PRIVATE -wd4100) endif() list(APPEND LIBS shp) elseif(GPSBABEL_WITH_SHAPELIB STREQUAL "custom") diff --git a/shapelib/LICENSE-MIT b/shapelib/LICENSE-MIT index 34fb3422c..159e87a02 100644 --- a/shapelib/LICENSE-MIT +++ b/shapelib/LICENSE-MIT @@ -1,6 +1,7 @@ MIT License -Copyright (c) 1999, Frank Warmerdam +Copyright (c) 2011-2024, Even Rouault +Copyright (c) 1999-2013, Frank Warmerdam Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/shapelib/README.GPSBabel b/shapelib/README.GPSBabel index f5bba78a8..03b89e225 100644 --- a/shapelib/README.GPSBabel +++ b/shapelib/README.GPSBabel @@ -1,4 +1,4 @@ -This is a subset of Shapelib v1.6.0 from http://shapelib.maptools.org/ +This is a subset of Shapelib v1.6.1 from http://shapelib.maptools.org/ The source is unmodified. It's subsetted here only to reduce the amount of size in our tree that it takes and to reduce ongoing diff --git a/shapelib/dbf_api.html b/shapelib/dbf_api.html index cdd29a22f..ed0216614 100644 --- a/shapelib/dbf_api.html +++ b/shapelib/dbf_api.html @@ -54,7 +54,7 @@ DBFHandle DBFCreate( const char * pszDBFFile );

DBFGetFieldCount()

-int DBFGetFieldCount( DBFHandle hDBF );
+int DBFGetFieldCount( const DBFHandle hDBF );
 
   hDBF:		The access handle for the file to be queried, as returned
                 by DBFOpen(), or DBFCreate().
@@ -68,7 +68,7 @@ int DBFGetFieldCount( DBFHandle hDBF );
 

DBFGetRecordCount()

-int DBFGetRecordCount( DBFHandle hDBF );
+int DBFGetRecordCount( const DBFHandle hDBF );
 
   hDBF:		The access handle for the file to be queried, as returned by
 		DBFOpen(), or DBFCreate().
@@ -83,7 +83,7 @@ int DBFGetRecordCount( DBFHandle hDBF );
 

DBFGetFieldIndex()

-int DBFGetFieldIndex( DBFHandle hDBF, const char *pszFieldName );
+int DBFGetFieldIndex( const DBFHandle hDBF, const char *pszFieldName );
 
   hDBF:		The access handle for the file to be queried, as returned by
 		DBFOpen(), or DBFCreate().
@@ -99,7 +99,8 @@ int DBFGetFieldIndex( DBFHandle hDBF, const char *pszFieldName );
 

DBFGetFieldInfo()

-DBFFieldType DBFGetFieldInfo( DBFHandle hDBF, int iField, char * pszFieldName,
+DBFFieldType DBFGetFieldInfo( const  DBFHandle hDBF, int iField,
+                              char * pszFieldName,
                               int * pnWidth, int * pnDecimals );
 
   hDBF:		The access handle for the file to be queried, as returned by
@@ -127,16 +128,16 @@ DBFFieldType DBFGetFieldInfo( DBFHandle hDBF, int iField, char * pszFieldName,
   The DBFGetFieldInfo() returns the type of the requested field, which is
   one of the DBFFieldType enumerated values.  As well, the field name, and
   field width information can optionally be returned.  The field type returned
-  does not correspond one to one with the xBase field types.  For instance
-  the xBase field type for Date will just be returned as being FTInteger.  

+ does not correspond one to one with the xBase field types.

     typedef enum {
-      FTString,			/* fixed length string field 		*/
-      FTInteger,		/* numeric field with no decimals 	*/
-      FTDouble,			/* numeric field with decimals 		*/
-      FTLogical,		/* logical field.                       */
-      FTInvalid                 /* not a recognised field type 		*/
+      FTString,			/* fixed length string field        */
+      FTInteger,		/* numeric field with no decimals   */
+      FTDouble,			/* numeric field with decimals      */
+      FTLogical,		/* logical field                    */
+      FTDate,			/* date field                       */
+      FTInvalid			/* not a recognised field type      */
     } DBFFieldType;
 
@@ -251,7 +252,7 @@ const char *DBFReadStringAttribute( DBFHandle hDBF, int iShape, int iField );

DBFIsAttributeNULL()

-int DBFIsAttributeNULL( DBFHandle hDBF, int iShape, int iField );
+int DBFIsAttributeNULL( const DBFHandle hDBF, int iShape, int iField );
 
   hDBF:		The access handle for the file to be queried, as returned by
 		DBFOpen(), or DBFCreate().
@@ -382,7 +383,7 @@ void DBFClose( DBFHandle hDBF );
 

DBFIsRecordDeleted()

-int DBFIsRecordDeleted( DBFHandle hDBF, int iShape );
+int DBFIsRecordDeleted( const DBFHandle hDBF, int iShape );
 
   hDBF:		The access handle for the file to be checked.
   iShape:       The record index to check.
@@ -410,7 +411,7 @@ int DBFMarkRecordDeleted( DBFHandle hDBF, int iShape, int bIsDeleted );
 

DBFGetNativeFieldType()

-char DBFGetNativeFieldType( DBFHandle hDBF, int iField );
+char DBFGetNativeFieldType( const DBFHandle hDBF, int iField );
 
   hDBF:		The access handle for the file.
   iField:       The field index to query.
diff --git a/shapelib/dbfopen.c b/shapelib/dbfopen.c
index ee5be97f0..90ed7ea8e 100644
--- a/shapelib/dbfopen.c
+++ b/shapelib/dbfopen.c
@@ -6,12 +6,12 @@
  *
  ******************************************************************************
  * Copyright (c) 1999, Frank Warmerdam
- * Copyright (c) 2012-2019, Even Rouault 
+ * Copyright (c) 2012-2024, Even Rouault 
  *
  * SPDX-License-Identifier: MIT OR LGPL-2.0-or-later
  ******************************************************************************/
 
-#include "shapefil.h"
+#include "shapefil_private.h"
 
 #include 
 #include 
@@ -26,7 +26,7 @@
 
 #if defined(_MSC_VER)
 #define STRCASECMP(a, b) (_stricmp(a, b))
-#elif defined(WIN32) || defined(_WIN32)
+#elif defined(_WIN32)
 #define STRCASECMP(a, b) (stricmp(a, b))
 #else
 #include 
@@ -37,7 +37,7 @@
 #if _MSC_VER < 1900
 #define snprintf _snprintf
 #endif
-#elif defined(WIN32) || defined(_WIN32)
+#elif defined(_WIN32)
 #ifndef snprintf
 #define snprintf _snprintf
 #endif
@@ -68,18 +68,6 @@ CPL_INLINE static void CPL_IGNORE_RET_VAL_INT(CPL_UNUSED int unused)
 #define CPL_IGNORE_RET_VAL_INT(x) x
 #endif
 
-#ifdef __cplusplus
-#define STATIC_CAST(type, x) static_cast(x)
-#define REINTERPRET_CAST(type, x) reinterpret_cast(x)
-#define CONST_CAST(type, x) const_cast(x)
-#define SHPLIB_NULLPTR nullptr
-#else
-#define STATIC_CAST(type, x) ((type)(x))
-#define REINTERPRET_CAST(type, x) ((type)(x))
-#define CONST_CAST(type, x) ((type)(x))
-#define SHPLIB_NULLPTR NULL
-#endif
-
 /************************************************************************/
 /*                           DBFWriteHeader()                           */
 /*                                                                      */
@@ -310,7 +298,6 @@ void SHPAPI_CALL DBFSetLastModifiedDate(DBFHandle psDBF, int nYYSince1900,
 /************************************************************************/
 
 DBFHandle SHPAPI_CALL DBFOpen(const char *pszFilename, const char *pszAccess)
-
 {
     SAHooks sHooks;
 
@@ -494,7 +481,7 @@ DBFHandle SHPAPI_CALL DBFOpenLL(const char *pszFilename, const char *pszAccess,
 
     for (int iField = 0; iField < nFields; iField++)
     {
-        unsigned char *pabyFInfo = pabyBuf + iField * XBASE_FLDHDR_SZ;
+        const unsigned char *pabyFInfo = pabyBuf + iField * XBASE_FLDHDR_SZ;
         if (pabyFInfo[0] == HEADER_RECORD_TERMINATOR)
         {
             psDBF->nFields = iField;
@@ -1077,7 +1064,6 @@ double SHPAPI_CALL DBFReadDoubleAttribute(DBFHandle psDBF, int iRecord,
 
 const char SHPAPI_CALL1(*)
     DBFReadStringAttribute(DBFHandle psDBF, int iRecord, int iField)
-
 {
     return STATIC_CAST(const char *,
                        DBFReadAttribute(psDBF, iRecord, iField, 'C'));
@@ -1091,19 +1077,49 @@ const char SHPAPI_CALL1(*)
 
 const char SHPAPI_CALL1(*)
     DBFReadLogicalAttribute(DBFHandle psDBF, int iRecord, int iField)
-
 {
     return STATIC_CAST(const char *,
                        DBFReadAttribute(psDBF, iRecord, iField, 'L'));
 }
 
+/************************************************************************/
+/*                        DBFReadDateAttribute()                        */
+/*                                                                      */
+/*      Read a date attribute.                                          */
+/************************************************************************/
+
+SHPDate SHPAPI_CALL DBFReadDateAttribute(DBFHandle psDBF, int iRecord,
+                                         int iField)
+{
+    const char *pdateValue = STATIC_CAST(
+        const char *, DBFReadAttribute(psDBF, iRecord, iField, 'D'));
+
+    SHPDate date;
+
+    if (pdateValue == SHPLIB_NULLPTR)
+    {
+        date.year = 0;
+        date.month = 0;
+        date.day = 0;
+    }
+    else if (3 != sscanf(pdateValue, "%4d%2d%2d", &date.year, &date.month,
+                         &date.day))
+    {
+        date.year = 0;
+        date.month = 0;
+        date.day = 0;
+    }
+
+    return date;
+}
+
 /************************************************************************/
 /*                         DBFIsValueNULL()                             */
 /*                                                                      */
 /*      Return TRUE if the passed string is NULL.                       */
 /************************************************************************/
 
-static bool DBFIsValueNULL(char chType, const char *pszValue)
+static bool DBFIsValueNULL(char chType, const char *pszValue, int size)
 {
     if (pszValue == SHPLIB_NULLPTR)
         return true;
@@ -1128,13 +1144,22 @@ static bool DBFIsValueNULL(char chType, const char *pszValue)
             return true;
 
         case 'D':
-            /* NULL date fields have value "00000000" */
+        {
+            const char DIGIT_ZERO = '0';
+            /* NULL date fields have value "00000000" or "0"*size */
             /* Some DBF files have fields filled with spaces */
             /* (trimmed by DBFReadStringAttribute) to indicate null */
             /* values for dates (#4265). */
             /* And others have '       0': https://lists.osgeo.org/pipermail/gdal-dev/2023-November/058010.html */
-            return strncmp(pszValue, "00000000", 8) == 0 ||
-                   strcmp(pszValue, " ") == 0 || strcmp(pszValue, "0") == 0;
+            /* And others just empty string: https://github.com/OSGeo/gdal/issues/10405 */
+            if (pszValue[0] == 0 || strncmp(pszValue, "00000000", 8) == 0 ||
+                strcmp(pszValue, " ") == 0 || strcmp(pszValue, "0") == 0)
+                return true;
+            for (int i = 0; i < size; i++)
+                if (pszValue[i] != DIGIT_ZERO)
+                    return false;
+            return true;
+        }
 
         case 'L':
             /* NULL boolean fields have value "?" */
@@ -1154,14 +1179,16 @@ static bool DBFIsValueNULL(char chType, const char *pszValue)
 /*      Contributed by Jim Matthews.                                    */
 /************************************************************************/
 
-int SHPAPI_CALL DBFIsAttributeNULL(DBFHandle psDBF, int iRecord, int iField)
+int SHPAPI_CALL DBFIsAttributeNULL(const DBFHandle psDBF, int iRecord,
+                                   int iField)
 {
     const char *pszValue = DBFReadStringAttribute(psDBF, iRecord, iField);
 
     if (pszValue == SHPLIB_NULLPTR)
         return TRUE;
 
-    return DBFIsValueNULL(psDBF->pachFieldType[iField], pszValue);
+    return DBFIsValueNULL(psDBF->pachFieldType[iField], pszValue,
+                          psDBF->panFieldSize[iField]);
 }
 
 /************************************************************************/
@@ -1170,8 +1197,7 @@ int SHPAPI_CALL DBFIsAttributeNULL(DBFHandle psDBF, int iRecord, int iField)
 /*      Return the number of fields in this table.                      */
 /************************************************************************/
 
-int SHPAPI_CALL DBFGetFieldCount(DBFHandle psDBF)
-
+int SHPAPI_CALL DBFGetFieldCount(const DBFHandle psDBF)
 {
     return (psDBF->nFields);
 }
@@ -1182,8 +1208,7 @@ int SHPAPI_CALL DBFGetFieldCount(DBFHandle psDBF)
 /*      Return the number of records in this table.                     */
 /************************************************************************/
 
-int SHPAPI_CALL DBFGetRecordCount(DBFHandle psDBF)
-
+int SHPAPI_CALL DBFGetRecordCount(const DBFHandle psDBF)
 {
     return (psDBF->nRecords);
 }
@@ -1196,10 +1221,9 @@ int SHPAPI_CALL DBFGetRecordCount(DBFHandle psDBF)
 /*      bytes long.                                                     */
 /************************************************************************/
 
-DBFFieldType SHPAPI_CALL DBFGetFieldInfo(DBFHandle psDBF, int iField,
+DBFFieldType SHPAPI_CALL DBFGetFieldInfo(const DBFHandle psDBF, int iField,
                                          char *pszFieldName, int *pnWidth,
                                          int *pnDecimals)
-
 {
     if (iField < 0 || iField >= psDBF->nFields)
         return (FTInvalid);
@@ -1341,8 +1365,14 @@ static bool DBFWriteAttribute(DBFHandle psDBF, int hEntity, int iField,
             if (psDBF->panFieldSize[iField] >= 1 &&
                 (*STATIC_CAST(char *, pValue) == 'F' ||
                  *STATIC_CAST(char *, pValue) == 'T'))
+            {
                 *(pabyRec + psDBF->panFieldOffset[iField]) =
                     *STATIC_CAST(char *, pValue);
+            }
+            else
+            {
+                nRetResult = false;
+            }
             break;
 
         default:
@@ -1422,17 +1452,17 @@ int SHPAPI_CALL DBFWriteAttributeDirectly(DBFHandle psDBF, int hEntity,
         /*      Assign all the record fields.                                   */
         /* -------------------------------------------------------------------- */
         int j;
-        if (STATIC_CAST(int, strlen(STATIC_CAST(char *, pValue))) >
+        if (STATIC_CAST(int, strlen(STATIC_CAST(const char *, pValue))) >
             psDBF->panFieldSize[iField])
             j = psDBF->panFieldSize[iField];
         else
         {
             memset(pabyRec + psDBF->panFieldOffset[iField], ' ',
                    psDBF->panFieldSize[iField]);
-            j = STATIC_CAST(int, strlen(STATIC_CAST(char *, pValue)));
+            j = STATIC_CAST(int, strlen(STATIC_CAST(const char *, pValue)));
         }
 
-        strncpy(
+        memcpy(
             REINTERPRET_CAST(char *, pabyRec + psDBF->panFieldOffset[iField]),
             STATIC_CAST(const char *, pValue), j);
     }
@@ -1459,7 +1489,7 @@ int SHPAPI_CALL DBFWriteDoubleAttribute(DBFHandle psDBF, int iRecord,
 /************************************************************************/
 /*                      DBFWriteIntegerAttribute()                      */
 /*                                                                      */
-/*      Write a integer attribute.                                      */
+/*      Write an integer attribute.                                     */
 /************************************************************************/
 
 int SHPAPI_CALL DBFWriteIntegerAttribute(DBFHandle psDBF, int iRecord,
@@ -1479,7 +1509,6 @@ int SHPAPI_CALL DBFWriteIntegerAttribute(DBFHandle psDBF, int iRecord,
 
 int SHPAPI_CALL DBFWriteStringAttribute(DBFHandle psDBF, int iRecord,
                                         int iField, const char *pszValue)
-
 {
     return (
         DBFWriteAttribute(psDBF, iRecord, iField,
@@ -1489,11 +1518,10 @@ int SHPAPI_CALL DBFWriteStringAttribute(DBFHandle psDBF, int iRecord,
 /************************************************************************/
 /*                      DBFWriteNULLAttribute()                         */
 /*                                                                      */
-/*      Write a string attribute.                                       */
+/*      Write a NULL attribute.                                         */
 /************************************************************************/
 
 int SHPAPI_CALL DBFWriteNULLAttribute(DBFHandle psDBF, int iRecord, int iField)
-
 {
     return (DBFWriteAttribute(psDBF, iRecord, iField, SHPLIB_NULLPTR));
 }
@@ -1506,13 +1534,36 @@ int SHPAPI_CALL DBFWriteNULLAttribute(DBFHandle psDBF, int iRecord, int iField)
 
 int SHPAPI_CALL DBFWriteLogicalAttribute(DBFHandle psDBF, int iRecord,
                                          int iField, const char lValue)
-
 {
     return (
         DBFWriteAttribute(psDBF, iRecord, iField,
                           STATIC_CAST(void *, CONST_CAST(char *, &lValue))));
 }
 
+/************************************************************************/
+/*                      DBFWriteDateAttribute()                         */
+/*                                                                      */
+/*      Write a date attribute.                                         */
+/************************************************************************/
+
+int SHPAPI_CALL DBFWriteDateAttribute(DBFHandle psDBF, int iRecord, int iField,
+                                      const SHPDate *lValue)
+{
+    if (SHPLIB_NULLPTR == lValue)
+        return false;
+    /* check for supported digit range, but do not check for valid date */
+    if (lValue->year < 0 || lValue->year > 9999)
+        return false;
+    if (lValue->month < 0 || lValue->month > 99)
+        return false;
+    if (lValue->day < 0 || lValue->day > 99)
+        return false;
+    char dateValue[9]; /* "yyyyMMdd\0" */
+    snprintf(dateValue, sizeof(dateValue), "%04d%02d%02d", lValue->year,
+             lValue->month, lValue->day);
+    return (DBFWriteAttributeDirectly(psDBF, iRecord, iField, dateValue));
+}
+
 /************************************************************************/
 /*                         DBFWriteTuple()                              */
 /*                                                                      */
@@ -1572,7 +1623,6 @@ int SHPAPI_CALL DBFWriteTuple(DBFHandle psDBF, int hEntity,
 /************************************************************************/
 
 const char SHPAPI_CALL1(*) DBFReadTuple(DBFHandle psDBF, int hEntity)
-
 {
     if (hEntity < 0 || hEntity >= psDBF->nRecords)
         return SHPLIB_NULLPTR;
@@ -1586,12 +1636,15 @@ const char SHPAPI_CALL1(*) DBFReadTuple(DBFHandle psDBF, int hEntity)
 /************************************************************************/
 /*                          DBFCloneEmpty()                             */
 /*                                                                      */
-/*      Read one of the attribute fields of a record.                   */
+/*      Create a new .dbf file with same code page and field            */
+/*      definitions as the given handle.                                */
 /************************************************************************/
 
-DBFHandle SHPAPI_CALL DBFCloneEmpty(DBFHandle psDBF, const char *pszFilename)
+DBFHandle SHPAPI_CALL DBFCloneEmpty(const DBFHandle psDBF,
+                                    const char *pszFilename)
 {
-    DBFHandle newDBF = DBFCreateEx(pszFilename, psDBF->pszCodePage);
+    DBFHandle newDBF =
+        DBFCreateLL(pszFilename, psDBF->pszCodePage, &psDBF->sHooks);
     if (newDBF == SHPLIB_NULLPTR)
         return SHPLIB_NULLPTR;
 
@@ -1648,8 +1701,7 @@ DBFHandle SHPAPI_CALL DBFCloneEmpty(DBFHandle psDBF, const char *pszFilename)
 /*                           'M' (Memo: 10 digits .DBT block ptr)       */
 /************************************************************************/
 
-char SHPAPI_CALL DBFGetNativeFieldType(DBFHandle psDBF, int iField)
-
+char SHPAPI_CALL DBFGetNativeFieldType(const DBFHandle psDBF, int iField)
 {
     if (iField >= 0 && iField < psDBF->nFields)
         return psDBF->pachFieldType[iField];
@@ -1665,7 +1717,8 @@ char SHPAPI_CALL DBFGetNativeFieldType(DBFHandle psDBF, int iField)
 /*      Contributed by Jim Matthews.                                    */
 /************************************************************************/
 
-int SHPAPI_CALL DBFGetFieldIndex(DBFHandle psDBF, const char *pszFieldName)
+int SHPAPI_CALL DBFGetFieldIndex(const DBFHandle psDBF,
+                                 const char *pszFieldName)
 {
     char name[XBASE_FLDNAME_LEN_READ + 1];
 
@@ -1685,7 +1738,7 @@ int SHPAPI_CALL DBFGetFieldIndex(DBFHandle psDBF, const char *pszFieldName)
 /*      it returns FALSE.                                               */
 /************************************************************************/
 
-int SHPAPI_CALL DBFIsRecordDeleted(DBFHandle psDBF, int iShape)
+int SHPAPI_CALL DBFIsRecordDeleted(const DBFHandle psDBF, int iShape)
 {
     /* -------------------------------------------------------------------- */
     /*      Verify selection.                                               */
@@ -1748,7 +1801,7 @@ int SHPAPI_CALL DBFMarkRecordDeleted(DBFHandle psDBF, int iShape,
 /*                            DBFGetCodePage                            */
 /************************************************************************/
 
-const char SHPAPI_CALL1(*) DBFGetCodePage(DBFHandle psDBF)
+const char SHPAPI_CALL1(*) DBFGetCodePage(const DBFHandle psDBF)
 {
     if (psDBF == SHPLIB_NULLPTR)
         return SHPLIB_NULLPTR;
@@ -1901,13 +1954,13 @@ int SHPAPI_CALL DBFReorderFields(DBFHandle psDBF, const int *panMap)
     /* a simple malloc() would be enough, but calloc() helps clang static
      * analyzer */
     int *panFieldOffsetNew =
-        STATIC_CAST(int *, calloc(sizeof(int), psDBF->nFields));
+        STATIC_CAST(int *, calloc(psDBF->nFields, sizeof(int)));
     int *panFieldSizeNew =
-        STATIC_CAST(int *, calloc(sizeof(int), psDBF->nFields));
+        STATIC_CAST(int *, calloc(psDBF->nFields, sizeof(int)));
     int *panFieldDecimalsNew =
-        STATIC_CAST(int *, calloc(sizeof(int), psDBF->nFields));
+        STATIC_CAST(int *, calloc(psDBF->nFields, sizeof(int)));
     char *pachFieldTypeNew =
-        STATIC_CAST(char *, calloc(sizeof(char), psDBF->nFields));
+        STATIC_CAST(char *, calloc(psDBF->nFields, sizeof(char)));
     char *pszHeaderNew = STATIC_CAST(
         char *, malloc(sizeof(char) * XBASE_FLDHDR_SZ * psDBF->nFields));
 
@@ -2103,7 +2156,6 @@ int SHPAPI_CALL DBFAlterFieldDefn(DBFHandle psDBF, int iField,
         char *pszOldField =
             STATIC_CAST(char *, malloc(sizeof(char) * (nOldWidth + 1)));
 
-        /* cppcheck-suppress uninitdata */
         pszOldField[nOldWidth] = 0;
 
         /* move records to their new positions */
@@ -2123,7 +2175,8 @@ int SHPAPI_CALL DBFAlterFieldDefn(DBFHandle psDBF, int iField,
             }
 
             memcpy(pszOldField, pszRecord + nOffset, nOldWidth);
-            const bool bIsNULL = DBFIsValueNULL(chOldType, pszOldField);
+            const bool bIsNULL =
+                DBFIsValueNULL(chOldType, pszOldField, nOldWidth);
 
             if (nWidth != nOldWidth)
             {
@@ -2181,7 +2234,6 @@ int SHPAPI_CALL DBFAlterFieldDefn(DBFHandle psDBF, int iField,
         char *pszOldField =
             STATIC_CAST(char *, malloc(sizeof(char) * (nOldWidth + 1)));
 
-        /* cppcheck-suppress uninitdata */
         pszOldField[nOldWidth] = 0;
 
         /* move records to their new positions */
@@ -2201,7 +2253,8 @@ int SHPAPI_CALL DBFAlterFieldDefn(DBFHandle psDBF, int iField,
             }
 
             memcpy(pszOldField, pszRecord + nOffset, nOldWidth);
-            const bool bIsNULL = DBFIsValueNULL(chOldType, pszOldField);
+            const bool bIsNULL =
+                DBFIsValueNULL(chOldType, pszOldField, nOldWidth);
 
             if (nOffset + nOldWidth < nOldRecordLength)
             {
diff --git a/shapelib/safileio.c b/shapelib/safileio.c
index b63a3933a..2799f8112 100644
--- a/shapelib/safileio.c
+++ b/shapelib/safileio.c
@@ -6,6 +6,7 @@
  *
  ******************************************************************************
  * Copyright (c) 2007, Frank Warmerdam
+ * Copyright (c) 2016-2024, Even Rouault 
  *
  * SPDX-License-Identifier: MIT OR LGPL-2.0-or-later
  ******************************************************************************
@@ -132,8 +133,10 @@ static wchar_t *Utf8ToWideChar(const char *pszFilename)
 /*                           SAUtf8WFOpen                               */
 /************************************************************************/
 
-SAFile SAUtf8WFOpen(const char *pszFilename, const char *pszAccess)
+static SAFile SAUtf8WFOpen(const char *pszFilename, const char *pszAccess,
+                           void *pvUserData)
 {
+    (void)pvUserData;
     SAFile file = NULL;
     wchar_t *pwszFileName = Utf8ToWideChar(pszFilename);
     wchar_t *pwszAccess = Utf8ToWideChar(pszAccess);
@@ -146,8 +149,9 @@ SAFile SAUtf8WFOpen(const char *pszFilename, const char *pszAccess)
     return file;
 }
 
-int SAUtf8WRemove(const char *pszFilename)
+static int SAUtf8WRemove(const char *pszFilename, void *pvUserData)
 {
+    (void)pvUserData;
     wchar_t *pwszFileName = Utf8ToWideChar(pszFilename);
     int rc = -1;
     if (pwszFileName != NULL)
diff --git a/shapelib/shapefil.h b/shapelib/shapefil.h
index 2328f15cc..47b2e30fd 100644
--- a/shapelib/shapefil.h
+++ b/shapelib/shapefil.h
@@ -9,7 +9,7 @@
  *
  ******************************************************************************
  * Copyright (c) 1999, Frank Warmerdam
- * Copyright (c) 2012-2016, Even Rouault 
+ * Copyright (c) 2012-2024, Even Rouault 
  *
  * SPDX-License-Identifier: MIT OR LGPL-2.0-or-later
  ******************************************************************************
@@ -27,22 +27,25 @@ extern "C"
 {
 #endif
 
-/************************************************************************/
-/*           Version related macros (added in 1.6.0)                    */
-/************************************************************************/
+    /************************************************************************/
+    /*           Version related macros (added in 1.6.0)                    */
+    /************************************************************************/
 
 #define SHAPELIB_VERSION_MAJOR 1
 #define SHAPELIB_VERSION_MINOR 6
-#define SHAPELIB_VERSION_MICRO 0
+#define SHAPELIB_VERSION_MICRO 1
 
-#define SHAPELIB_MAKE_VERSION_NUMBER(major, minor, micro) \
+#define SHAPELIB_MAKE_VERSION_NUMBER(major, minor, micro)                      \
     ((major) * 10000 + (minor) * 100 + (micro))
 
-#define SHAPELIB_VERSION_NUMBER \
-    SHAPELIB_MAKE_VERSION_NUMBER(SHAPELIB_VERSION_MAJOR, SHAPELIB_VERSION_MINOR, SHAPELIB_VERSION_MICRO)
+#define SHAPELIB_VERSION_NUMBER                                                \
+    SHAPELIB_MAKE_VERSION_NUMBER(SHAPELIB_VERSION_MAJOR,                       \
+                                 SHAPELIB_VERSION_MINOR,                       \
+                                 SHAPELIB_VERSION_MICRO)
 
-#define SHAPELIB_AT_LEAST(major, minor, micro) \
-    (SHAPELIB_VERSION_NUMBER >= SHAPELIB_MAKE_VERSION_NUMBER(major, minor, micro))
+#define SHAPELIB_AT_LEAST(major, minor, micro)                                 \
+    (SHAPELIB_VERSION_NUMBER >=                                                \
+     SHAPELIB_MAKE_VERSION_NUMBER(major, minor, micro))
 
 /************************************************************************/
 /*                        Configuration options.                        */
@@ -112,7 +115,7 @@ extern "C"
 /*      On some platforms, additional file IO hooks are defined that    */
 /*      UTF-8 encoded filenames Unicode filenames                       */
 /* -------------------------------------------------------------------- */
-#if defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
+#if defined(_WIN32)
 #define SHPAPI_WINDOWS
 #define SHPAPI_UTF8_HOOKS
 #endif
@@ -190,6 +193,13 @@ extern "C"
 
     typedef SHPInfo *SHPHandle;
 
+    typedef struct
+    {
+        int year;
+        int month;
+        int day;
+    } SHPDate;
+
 /* -------------------------------------------------------------------- */
 /*      Shape types (nSHPType)                                          */
 /* -------------------------------------------------------------------- */
@@ -221,7 +231,7 @@ extern "C"
 #define SHPP_RING 5
 
     /* -------------------------------------------------------------------- */
-    /*      SHPObject - represents on shape (without attributes) read       */
+    /*      SHPObject - represents one shape (without attributes) read      */
     /*      from the .shp file.                                             */
     /* -------------------------------------------------------------------- */
     struct tagSHPObject
@@ -282,13 +292,13 @@ extern "C"
     SHPHandle SHPAPI_CALL SHPCreate(const char *pszShapeFile, int nShapeType);
     SHPHandle SHPAPI_CALL SHPCreateLL(const char *pszShapeFile, int nShapeType,
                                       const SAHooks *psHooks);
-    void SHPAPI_CALL SHPGetInfo(SHPHandle hSHP, int *pnEntities,
+    void SHPAPI_CALL SHPGetInfo(const SHPHandle hSHP, int *pnEntities,
                                 int *pnShapeType, double *padfMinBound,
                                 double *padfMaxBound);
 
-    SHPObject SHPAPI_CALL1(*) SHPReadObject(SHPHandle hSHP, int iShape);
+    SHPObject SHPAPI_CALL1(*) SHPReadObject(const SHPHandle hSHP, int iShape);
     int SHPAPI_CALL SHPWriteObject(SHPHandle hSHP, int iShape,
-                                   SHPObject *psObject);
+                                   const SHPObject *psObject);
 
     void SHPAPI_CALL SHPDestroyObject(SHPObject *psObject);
     void SHPAPI_CALL SHPComputeExtents(SHPObject *psObject);
@@ -301,7 +311,7 @@ extern "C"
         SHPCreateSimpleObject(int nSHPType, int nVertices, const double *padfX,
                               const double *padfY, const double *padfZ);
 
-    int SHPAPI_CALL SHPRewindObject(SHPHandle hSHP, SHPObject *psObject);
+    int SHPAPI_CALL SHPRewindObject(const SHPHandle hSHP, SHPObject *psObject);
 
     void SHPAPI_CALL SHPClose(SHPHandle hSHP);
     void SHPAPI_CALL SHPWriteHeader(SHPHandle hSHP);
@@ -355,12 +365,11 @@ extern "C"
     int SHPAPI_CALL SHPWriteTree(SHPTree *hTree, const char *pszFilename);
 
     int SHPAPI_CALL SHPTreeAddShapeId(SHPTree *hTree, SHPObject *psObject);
-    int SHPAPI_CALL SHPTreeRemoveShapeId(SHPTree *hTree, int nShapeId);
 
     void SHPAPI_CALL SHPTreeTrimExtraNodes(SHPTree *hTree);
 
     int SHPAPI_CALL1(*)
-        SHPTreeFindLikelyShapes(SHPTree *hTree, double *padfBoundsMin,
+        SHPTreeFindLikelyShapes(const SHPTree *hTree, double *padfBoundsMin,
                                 double *padfBoundsMax, int *);
     int SHPAPI_CALL SHPCheckBoundsOverlap(const double *, const double *,
                                           const double *, const double *, int);
@@ -377,8 +386,9 @@ extern "C"
     void SHPAPI_CALL SHPCloseDiskTree(SHPTreeDiskHandle hDiskTree);
 
     int SHPAPI_CALL1(*)
-        SHPSearchDiskTreeEx(SHPTreeDiskHandle hDiskTree, double *padfBoundsMin,
-                            double *padfBoundsMax, int *pnShapeCount);
+        SHPSearchDiskTreeEx(const SHPTreeDiskHandle hDiskTree,
+                            double *padfBoundsMin, double *padfBoundsMax,
+                            int *pnShapeCount);
 
     int SHPAPI_CALL SHPWriteTreeLL(SHPTree *hTree, const char *pszFilename,
                                    const SAHooks *psHooks);
@@ -395,12 +405,14 @@ extern "C"
     void SHPAPI_CALL SBNCloseDiskTree(SBNSearchHandle hSBN);
 
     int SHPAPI_CALL1(*)
-        SBNSearchDiskTree(SBNSearchHandle hSBN, const double *padfBoundsMin,
+        SBNSearchDiskTree(const SBNSearchHandle hSBN,
+                          const double *padfBoundsMin,
                           const double *padfBoundsMax, int *pnShapeCount);
 
     int SHPAPI_CALL1(*)
-        SBNSearchDiskTreeInteger(SBNSearchHandle hSBN, int bMinX, int bMinY,
-                                 int bMaxX, int bMaxY, int *pnShapeCount);
+        SBNSearchDiskTreeInteger(const SBNSearchHandle hSBN, int bMinX,
+                                 int bMinY, int bMaxX, int bMaxY,
+                                 int *pnShapeCount);
 
     void SHPAPI_CALL SBNSearchFreeIds(int *panShapeId);
 
@@ -488,8 +500,8 @@ extern "C"
                                       const char *pszCodePage,
                                       const SAHooks *psHooks);
 
-    int SHPAPI_CALL DBFGetFieldCount(DBFHandle psDBF);
-    int SHPAPI_CALL DBFGetRecordCount(DBFHandle psDBF);
+    int SHPAPI_CALL DBFGetFieldCount(const DBFHandle psDBF);
+    int SHPAPI_CALL DBFGetRecordCount(const DBFHandle psDBF);
     int SHPAPI_CALL DBFAddField(DBFHandle hDBF, const char *pszFieldName,
                                 DBFFieldType eType, int nWidth, int nDecimals);
 
@@ -505,11 +517,12 @@ extern "C"
                                       const char *pszFieldName, char chType,
                                       int nWidth, int nDecimals);
 
-    DBFFieldType SHPAPI_CALL DBFGetFieldInfo(DBFHandle psDBF, int iField,
+    DBFFieldType SHPAPI_CALL DBFGetFieldInfo(const DBFHandle psDBF, int iField,
                                              char *pszFieldName, int *pnWidth,
                                              int *pnDecimals);
 
-    int SHPAPI_CALL DBFGetFieldIndex(DBFHandle psDBF, const char *pszFieldName);
+    int SHPAPI_CALL DBFGetFieldIndex(const DBFHandle psDBF,
+                                     const char *pszFieldName);
 
     int SHPAPI_CALL DBFReadIntegerAttribute(DBFHandle hDBF, int iShape,
                                             int iField);
@@ -519,7 +532,10 @@ extern "C"
         DBFReadStringAttribute(DBFHandle hDBF, int iShape, int iField);
     const char SHPAPI_CALL1(*)
         DBFReadLogicalAttribute(DBFHandle hDBF, int iShape, int iField);
-    int SHPAPI_CALL DBFIsAttributeNULL(DBFHandle hDBF, int iShape, int iField);
+    SHPDate SHPAPI_CALL DBFReadDateAttribute(DBFHandle hDBF, int iShape,
+                                             int iField);
+    int SHPAPI_CALL DBFIsAttributeNULL(const DBFHandle hDBF, int iShape,
+                                       int iField);
 
     int SHPAPI_CALL DBFWriteIntegerAttribute(DBFHandle hDBF, int iShape,
                                              int iField, int nFieldValue);
@@ -534,24 +550,27 @@ extern "C"
     int SHPAPI_CALL DBFWriteLogicalAttribute(DBFHandle hDBF, int iShape,
                                              int iField,
                                              const char lFieldValue);
+    int SHPAPI_CALL DBFWriteDateAttribute(DBFHandle hDBF, int iShape,
+                                          int iField,
+                                          const SHPDate *dateFieldValue);
     int SHPAPI_CALL DBFWriteAttributeDirectly(DBFHandle psDBF, int hEntity,
                                               int iField, const void *pValue);
     const char SHPAPI_CALL1(*) DBFReadTuple(DBFHandle psDBF, int hEntity);
     int SHPAPI_CALL DBFWriteTuple(DBFHandle psDBF, int hEntity,
                                   const void *pRawTuple);
 
-    int SHPAPI_CALL DBFIsRecordDeleted(DBFHandle psDBF, int iShape);
+    int SHPAPI_CALL DBFIsRecordDeleted(const DBFHandle psDBF, int iShape);
     int SHPAPI_CALL DBFMarkRecordDeleted(DBFHandle psDBF, int iShape,
                                          int bIsDeleted);
 
-    DBFHandle SHPAPI_CALL DBFCloneEmpty(DBFHandle psDBF,
+    DBFHandle SHPAPI_CALL DBFCloneEmpty(const DBFHandle psDBF,
                                         const char *pszFilename);
 
     void SHPAPI_CALL DBFClose(DBFHandle hDBF);
     void SHPAPI_CALL DBFUpdateHeader(DBFHandle hDBF);
-    char SHPAPI_CALL DBFGetNativeFieldType(DBFHandle hDBF, int iField);
+    char SHPAPI_CALL DBFGetNativeFieldType(const DBFHandle hDBF, int iField);
 
-    const char SHPAPI_CALL1(*) DBFGetCodePage(DBFHandle psDBF);
+    const char SHPAPI_CALL1(*) DBFGetCodePage(const DBFHandle psDBF);
 
     void SHPAPI_CALL DBFSetLastModifiedDate(DBFHandle psDBF, int nYYSince1900,
                                             int nMM, int nDD);
diff --git a/shapelib/shapefil_private.h b/shapelib/shapefil_private.h
new file mode 100644
index 000000000..fd9ea93eb
--- /dev/null
+++ b/shapelib/shapefil_private.h
@@ -0,0 +1,117 @@
+#ifndef SHAPEFILE_PRIVATE_H_INCLUDED
+#define SHAPEFILE_PRIVATE_H_INCLUDED
+
+/******************************************************************************
+ *
+ * Project:  Shapelib
+ * Purpose:  Private include file for Shapelib.
+ * Author:   Frank Warmerdam, warmerdam@pobox.com
+ *
+ ******************************************************************************
+ * Copyright (c) 1999, Frank Warmerdam
+ * Copyright (c) 2012-2024, Even Rouault 
+ *
+ * SPDX-License-Identifier: MIT OR LGPL-2.0-or-later
+ ******************************************************************************
+ *
+ */
+
+#ifdef __cplusplus
+#define STATIC_CAST(type, x) static_cast(x)
+#define REINTERPRET_CAST(type, x) reinterpret_cast(x)
+#define CONST_CAST(type, x) const_cast(x)
+#define SHPLIB_NULLPTR nullptr
+#else
+#define STATIC_CAST(type, x) ((type)(x))
+#define REINTERPRET_CAST(type, x) ((type)(x))
+#define CONST_CAST(type, x) ((type)(x))
+#define SHPLIB_NULLPTR NULL
+#endif
+
+#if !defined(SHP_BIG_ENDIAN)
+#if defined(CPL_MSB)
+#define SHP_BIG_ENDIAN 1
+#elif (defined(__GNUC__) && __GNUC__ >= 5) ||                                  \
+    (defined(__GNUC__) && defined(__GNUC_MINOR__) && __GNUC__ == 4 &&          \
+     __GNUC_MINOR__ >= 6)
+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+#define SHP_BIG_ENDIAN 1
+#endif
+#elif defined(__GLIBC__)
+#if __BYTE_ORDER == __BIG_ENDIAN
+#define SHP_BIG_ENDIAN 1
+#endif
+#elif defined(_BIG_ENDIAN) && !defined(_LITTLE_ENDIAN)
+#define SHP_BIG_ENDIAN 1
+#elif defined(_LITTLE_ENDIAN) && !defined(_BIG_ENDIAN)
+#elif defined(__sparc) || defined(__sparc__) || defined(_POWER) ||             \
+    defined(__powerpc__) || defined(__ppc__) || defined(__hpux) ||             \
+    defined(_MIPSEB) || defined(_POWER) || defined(__s390__)
+#define SHP_BIG_ENDIAN 1
+#endif
+#endif
+
+#include "shapefil.h"
+#include 
+#include 
+
+/************************************************************************/
+/*        Little endian <==> big endian byte swap macros.               */
+/************************************************************************/
+
+#if (defined(__GNUC__) && __GNUC__ >= 5) ||                                    \
+    (defined(__GNUC__) && defined(__GNUC_MINOR__) && __GNUC__ == 4 &&          \
+     __GNUC_MINOR__ >= 8)
+#define _SHP_SWAP32(x)                                                         \
+    STATIC_CAST(uint32_t, __builtin_bswap32(STATIC_CAST(uint32_t, x)))
+#define _SHP_SWAP64(x)                                                         \
+    STATIC_CAST(uint64_t, __builtin_bswap64(STATIC_CAST(uint64_t, x)))
+#elif defined(_MSC_VER)
+#define _SHP_SWAP32(x)                                                         \
+    STATIC_CAST(uint32_t, _byteswap_ulong(STATIC_CAST(uint32_t, x)))
+#define _SHP_SWAP64(x)                                                         \
+    STATIC_CAST(uint64_t, _byteswap_uint64(STATIC_CAST(uint64_t, x)))
+#else
+#define _SHP_SWAP32(x)                                                         \
+    STATIC_CAST(uint32_t,                                                      \
+                ((STATIC_CAST(uint32_t, x) & 0x000000ffU) << 24) |             \
+                    ((STATIC_CAST(uint32_t, x) & 0x0000ff00U) << 8) |          \
+                    ((STATIC_CAST(uint32_t, x) & 0x00ff0000U) >> 8) |          \
+                    ((STATIC_CAST(uint32_t, x) & 0xff000000U) >> 24))
+#define _SHP_SWAP64(x)                                                         \
+    ((STATIC_CAST(uint64_t, _SHP_SWAP32(STATIC_CAST(uint32_t, x))) << 32) |    \
+     (STATIC_CAST(uint64_t, _SHP_SWAP32(STATIC_CAST(                           \
+                                uint32_t, STATIC_CAST(uint64_t, x) >> 32)))))
+
+#endif
+
+/* in-place uint32_t* swap */
+#define SHP_SWAP32(p)                                                          \
+    *REINTERPRET_CAST(uint32_t *, p) =                                         \
+        _SHP_SWAP32(*REINTERPRET_CAST(uint32_t *, p))
+/* in-place uint64_t* swap */
+#define SHP_SWAP64(p)                                                          \
+    *REINTERPRET_CAST(uint64_t *, p) =                                         \
+        _SHP_SWAP64(*REINTERPRET_CAST(uint64_t *, p))
+/* in-place double* swap */
+#define SHP_SWAPDOUBLE(x)                                                      \
+    do                                                                         \
+    {                                                                          \
+        uint64_t _n64;                                                         \
+        void *_lx = x;                                                         \
+        memcpy(&_n64, _lx, 8);                                                 \
+        _n64 = _SHP_SWAP64(_n64);                                              \
+        memcpy(_lx, &_n64, 8);                                                 \
+    } while (0)
+/* copy double* swap*/
+#define SHP_SWAPDOUBLE_CPY(dst, src)                                           \
+    do                                                                         \
+    {                                                                          \
+        uint64_t _n64;                                                         \
+        const void *_ls = src;                                                 \
+        void *_ld = dst;                                                       \
+        memcpy(&_n64, _ls, 8);                                                 \
+        _n64 = _SHP_SWAP64(_n64);                                              \
+        memcpy(_ld, &_n64, 8);                                                 \
+    } while (0)
+#endif /* ndef SHAPEFILE_PRIVATE_H_INCLUDED */
diff --git a/shapelib/shp_api.html b/shapelib/shp_api.html
index 55900bd6f..f80a25a0e 100644
--- a/shapelib/shp_api.html
+++ b/shapelib/shp_api.html
@@ -82,6 +82,9 @@ should be disposed of with SHPDestroyObject().

double dfYMax; double dfZMax; double dfMMax; + + int bMeasureIsUsed; + int bFastModeReadObject; } SHPObject;

@@ -113,7 +116,7 @@ SHPHandle SHPOpen( const char * pszShapeFile, const char * pszAccess );

SHPGetInfo()

-void SHPGetInfo( SHPHandle hSHP, int * pnEntities, int * pnShapeType,
+void SHPGetInfo( const SHPHandle hSHP, int * pnEntities, int * pnShapeType,
                  double * padfMinBound, double * padfMaxBound );
 
   hSHP:			The handle previously returned by SHPOpen()
@@ -143,7 +146,7 @@ void SHPGetInfo( SHPHandle hSHP, int * pnEntities, int * pnShapeType,
 

SHPReadObject()

-SHPObject *SHPReadObject( SHPHandle hSHP, int iShape );
+SHPObject *SHPReadObject( const SHPHandle hSHP, int iShape );
 
   hSHP:			The handle previously returned by SHPOpen()
 			or SHPCreate().
@@ -210,7 +213,8 @@ SHPHandle SHPCreate( const char * pszShapeFile, int nShapeType );
 
 SHPObject *
      SHPCreateSimpleObject( int nSHPType, int nVertices,
-			    double *padfX, double * padfY, double *padfZ, );
+			    const double *padfX, const double * padfY,
+			    const double *padfZ );
 
   nSHPType:		The SHPT_ type of the object to be created, such
                         as SHPT_POINT, or SHPT_POLYGON.
@@ -250,9 +254,10 @@ SHPObject *
 
 SHPObject *
      SHPCreateObject( int nSHPType, int iShape,
-                      int nParts, int * panPartStart, int * panPartType,
-                      int nVertices, double *padfX, double * padfY,
-                      double *padfZ, double *padfM );
+                      int nParts, const int * panPartStart,
+                      const int * panPartType,
+                      int nVertices, const double *padfX, const double * padfY,
+                      const double *padfZ, const double *padfM );
 
   nSHPType:		The SHPT_ type of the object to be created, such
                         as SHPT_POINT, or SHPT_POLYGON.
@@ -321,7 +326,7 @@ void SHPComputeExtents( SHPObject * psObject );
 

SHPWriteObject()

-int SHPWriteObject( SHPHandle hSHP, int iShape, SHPObject *psObject );
+int SHPWriteObject( SHPHandle hSHP, int iShape, const SHPObject *psObject );
 
   hSHP:			The handle previously returned by SHPOpen("r+")
 			or SHPCreate().
diff --git a/shapelib/shpopen.c b/shapelib/shpopen.c
index 2cf982ddf..014e15770 100644
--- a/shapelib/shpopen.c
+++ b/shapelib/shpopen.c
@@ -6,12 +6,12 @@
  *
  ******************************************************************************
  * Copyright (c) 1999, 2001, Frank Warmerdam
- * Copyright (c) 2011-2019, Even Rouault 
+ * Copyright (c) 2011-2024, Even Rouault 
  *
  * SPDX-License-Identifier: MIT OR LGPL-2.0-or-later
  ******************************************************************************/
 
-#include "shapefil.h"
+#include "shapefil_private.h"
 
 #include 
 #include 
@@ -39,60 +39,17 @@
 #if _MSC_VER < 1900
 #define snprintf _snprintf
 #endif
-#elif defined(WIN32) || defined(_WIN32)
+#elif defined(_WIN32)
 #ifndef snprintf
 #define snprintf _snprintf
 #endif
 #endif
 #endif
 
-#ifndef CPL_UNUSED
-#if defined(__GNUC__) && __GNUC__ >= 4
-#define CPL_UNUSED __attribute((__unused__))
-#else
-#define CPL_UNUSED
-#endif
-#endif
-
-#ifndef bBigEndian
-#if defined(CPL_LSB)
-#define bBigEndian false
-#elif defined(CPL_MSB)
-#define bBigEndian true
-#else
-#ifndef static_var_bBigEndian_defined
-#define static_var_bBigEndian_defined
-static bool bBigEndian = false;
-#endif
-#endif
-#endif
-
-#ifdef __cplusplus
-#define STATIC_CAST(type, x) static_cast(x)
-#define SHPLIB_NULLPTR nullptr
-#else
-#define STATIC_CAST(type, x) ((type)(x))
-#define SHPLIB_NULLPTR NULL
-#endif
-
-/************************************************************************/
-/*                              SwapWord()                              */
-/*                                                                      */
-/*      Swap a 2, 4 or 8 byte word.                                     */
-/************************************************************************/
-
-#ifndef SwapWord_defined
-#define SwapWord_defined
-static void SwapWord(int length, void *wordP)
-{
-    for (int i = 0; i < length / 2; i++)
-    {
-        const unsigned char temp = STATIC_CAST(unsigned char *, wordP)[i];
-        STATIC_CAST(unsigned char *, wordP)
-        [i] = STATIC_CAST(unsigned char *, wordP)[length - i - 1];
-        STATIC_CAST(unsigned char *, wordP)[length - i - 1] = temp;
-    }
-}
+/* Allows customization of the message in vendored builds (such as GDAL) */
+#ifndef SHP_RESTORE_SHX_HINT_MESSAGE
+#define SHP_RESTORE_SHX_HINT_MESSAGE                                           \
+    " Use SHPRestoreSHX() to restore or create it."
 #endif
 
 /************************************************************************/
@@ -120,58 +77,67 @@ void SHPAPI_CALL SHPWriteHeader(SHPHandle psSHP)
 
     uint32_t i32 = psSHP->nFileSize / 2; /* file size */
     ByteCopy(&i32, abyHeader + 24, 4);
-    if (!bBigEndian)
-        SwapWord(4, abyHeader + 24);
+#if !defined(SHP_BIG_ENDIAN)
+    SHP_SWAP32(abyHeader + 24);
+#endif
 
     i32 = 1000; /* version */
     ByteCopy(&i32, abyHeader + 28, 4);
-    if (bBigEndian)
-        SwapWord(4, abyHeader + 28);
+#if defined(SHP_BIG_ENDIAN)
+    SHP_SWAP32(abyHeader + 28);
+#endif
 
     i32 = psSHP->nShapeType; /* shape type */
     ByteCopy(&i32, abyHeader + 32, 4);
-    if (bBigEndian)
-        SwapWord(4, abyHeader + 32);
+#if defined(SHP_BIG_ENDIAN)
+    SHP_SWAP32(abyHeader + 32);
+#endif
 
     double dValue = psSHP->adBoundsMin[0]; /* set bounds */
     ByteCopy(&dValue, abyHeader + 36, 8);
-    if (bBigEndian)
-        SwapWord(8, abyHeader + 36);
-
+#if defined(SHP_BIG_ENDIAN)
+    SHP_SWAP64(abyHeader + 36);
+#endif
     dValue = psSHP->adBoundsMin[1];
     ByteCopy(&dValue, abyHeader + 44, 8);
-    if (bBigEndian)
-        SwapWord(8, abyHeader + 44);
-
+#if defined(SHP_BIG_ENDIAN)
+    SHP_SWAP64(abyHeader + 44);
+#endif
     dValue = psSHP->adBoundsMax[0];
     ByteCopy(&dValue, abyHeader + 52, 8);
-    if (bBigEndian)
-        SwapWord(8, abyHeader + 52);
+#if defined(SHP_BIG_ENDIAN)
+    SHP_SWAP64(abyHeader + 52);
+#endif
 
     dValue = psSHP->adBoundsMax[1];
     ByteCopy(&dValue, abyHeader + 60, 8);
-    if (bBigEndian)
-        SwapWord(8, abyHeader + 60);
+#if defined(SHP_BIG_ENDIAN)
+    SHP_SWAP64(abyHeader + 60);
+#endif
 
     dValue = psSHP->adBoundsMin[2]; /* z */
     ByteCopy(&dValue, abyHeader + 68, 8);
-    if (bBigEndian)
-        SwapWord(8, abyHeader + 68);
+#if defined(SHP_BIG_ENDIAN)
+    SHP_SWAP64(abyHeader + 68);
+#endif
 
     dValue = psSHP->adBoundsMax[2];
     ByteCopy(&dValue, abyHeader + 76, 8);
-    if (bBigEndian)
-        SwapWord(8, abyHeader + 76);
+#if defined(SHP_BIG_ENDIAN)
+    SHP_SWAP64(abyHeader + 76);
+#endif
 
     dValue = psSHP->adBoundsMin[3]; /* m */
     ByteCopy(&dValue, abyHeader + 84, 8);
-    if (bBigEndian)
-        SwapWord(8, abyHeader + 84);
+#if defined(SHP_BIG_ENDIAN)
+    SHP_SWAP64(abyHeader + 84);
+#endif
 
     dValue = psSHP->adBoundsMax[3];
     ByteCopy(&dValue, abyHeader + 92, 8);
-    if (bBigEndian)
-        SwapWord(8, abyHeader + 92);
+#if defined(SHP_BIG_ENDIAN)
+    SHP_SWAP64(abyHeader + 92);
+#endif
 
     /* -------------------------------------------------------------------- */
     /*      Write .shp file header.                                         */
@@ -193,8 +159,9 @@ void SHPAPI_CALL SHPWriteHeader(SHPHandle psSHP)
     /* -------------------------------------------------------------------- */
     i32 = (psSHP->nRecords * 2 * sizeof(uint32_t) + 100) / 2; /* file size */
     ByteCopy(&i32, abyHeader + 24, 4);
-    if (!bBigEndian)
-        SwapWord(4, abyHeader + 24);
+#if !defined(SHP_BIG_ENDIAN)
+    SHP_SWAP32(abyHeader + 24);
+#endif
 
     if (psSHP->sHooks.FSeek(psSHP->fpSHX, 0, 0) != 0 ||
         psSHP->sHooks.FWrite(abyHeader, 100, 1, psSHP->fpSHX) != 1)
@@ -224,10 +191,10 @@ void SHPAPI_CALL SHPWriteHeader(SHPHandle psSHP)
     {
         panSHX[i * 2] = psSHP->panRecOffset[i] / 2;
         panSHX[i * 2 + 1] = psSHP->panRecSize[i] / 2;
-        if (!bBigEndian)
-            SwapWord(4, panSHX + i * 2);
-        if (!bBigEndian)
-            SwapWord(4, panSHX + i * 2 + 1);
+#if !defined(SHP_BIG_ENDIAN)
+        SHP_SWAP32(panSHX + i * 2);
+        SHP_SWAP32(panSHX + i * 2 + 1);
+#endif
     }
 
     if (STATIC_CAST(int, psSHP->sHooks.FWrite(panSHX, sizeof(uint32_t) * 2,
@@ -309,23 +276,10 @@ SHPHandle SHPAPI_CALL SHPOpenLL(const char *pszLayer, const char *pszAccess,
         pszAccess = "rb";
     }
 
-/* -------------------------------------------------------------------- */
-/*  Establish the byte order on this machine.           */
-/* -------------------------------------------------------------------- */
-#if !defined(bBigEndian)
-    {
-        int i = 1;
-        if (*((unsigned char *)&i) == 1)
-            bBigEndian = false;
-        else
-            bBigEndian = true;
-    }
-#endif
-
     /* -------------------------------------------------------------------- */
     /*  Initialize the info structure.                  */
     /* -------------------------------------------------------------------- */
-    SHPHandle psSHP = STATIC_CAST(SHPHandle, calloc(sizeof(SHPInfo), 1));
+    SHPHandle psSHP = STATIC_CAST(SHPHandle, calloc(1, sizeof(SHPInfo)));
 
     psSHP->bUpdated = FALSE;
     memcpy(&(psSHP->sHooks), psHooks, sizeof(SAHooks));
@@ -376,14 +330,14 @@ SHPHandle SHPAPI_CALL SHPOpenLL(const char *pszLayer, const char *pszAccess,
 
     if (psSHP->fpSHX == SHPLIB_NULLPTR)
     {
-        const size_t nMessageLen = strlen(pszFullname) * 2 + 256;
+        const size_t nMessageLen =
+            64 + strlen(pszFullname) * 2 + strlen(SHP_RESTORE_SHX_HINT_MESSAGE);
         char *pszMessage = STATIC_CAST(char *, malloc(nMessageLen));
         pszFullname[nLenWithoutExtension] = 0;
-        snprintf(pszMessage, nMessageLen,
-                 "Unable to open %s.shx or %s.SHX. "
-                 "Set SHAPE_RESTORE_SHX config option to YES to restore or "
-                 "create it.",
-                 pszFullname, pszFullname);
+        snprintf(
+            pszMessage, nMessageLen,
+            "Unable to open %s.shx or %s.SHX." SHP_RESTORE_SHX_HINT_MESSAGE,
+            pszFullname, pszFullname);
         psHooks->Error(pszMessage);
         free(pszMessage);
 
@@ -476,43 +430,51 @@ SHPHandle SHPAPI_CALL SHPOpenLL(const char *pszLayer, const char *pszAccess,
     /* -------------------------------------------------------------------- */
     double dValue;
 
-    if (bBigEndian)
-        SwapWord(8, pabyBuf + 36);
+#if defined(SHP_BIG_ENDIAN)
+    SHP_SWAP64(pabyBuf + 36);
+#endif
     memcpy(&dValue, pabyBuf + 36, 8);
     psSHP->adBoundsMin[0] = dValue;
 
-    if (bBigEndian)
-        SwapWord(8, pabyBuf + 44);
+#if defined(SHP_BIG_ENDIAN)
+    SHP_SWAP64(pabyBuf + 44);
+#endif
     memcpy(&dValue, pabyBuf + 44, 8);
     psSHP->adBoundsMin[1] = dValue;
 
-    if (bBigEndian)
-        SwapWord(8, pabyBuf + 52);
+#if defined(SHP_BIG_ENDIAN)
+    SHP_SWAP64(pabyBuf + 52);
+#endif
     memcpy(&dValue, pabyBuf + 52, 8);
     psSHP->adBoundsMax[0] = dValue;
 
-    if (bBigEndian)
-        SwapWord(8, pabyBuf + 60);
+#if defined(SHP_BIG_ENDIAN)
+    SHP_SWAP64(pabyBuf + 60);
+#endif
     memcpy(&dValue, pabyBuf + 60, 8);
     psSHP->adBoundsMax[1] = dValue;
 
-    if (bBigEndian)
-        SwapWord(8, pabyBuf + 68); /* z */
+#if defined(SHP_BIG_ENDIAN)
+    SHP_SWAP64(pabyBuf + 68); /* z */
+#endif
     memcpy(&dValue, pabyBuf + 68, 8);
     psSHP->adBoundsMin[2] = dValue;
 
-    if (bBigEndian)
-        SwapWord(8, pabyBuf + 76);
+#if defined(SHP_BIG_ENDIAN)
+    SHP_SWAP64(pabyBuf + 76);
+#endif
     memcpy(&dValue, pabyBuf + 76, 8);
     psSHP->adBoundsMax[2] = dValue;
 
-    if (bBigEndian)
-        SwapWord(8, pabyBuf + 84); /* z */
+#if defined(SHP_BIG_ENDIAN)
+    SHP_SWAP64(pabyBuf + 84); /* z */
+#endif
     memcpy(&dValue, pabyBuf + 84, 8);
     psSHP->adBoundsMin[3] = dValue;
 
-    if (bBigEndian)
-        SwapWord(8, pabyBuf + 92);
+#if defined(SHP_BIG_ENDIAN)
+    SHP_SWAP64(pabyBuf + 92);
+#endif
     memcpy(&dValue, pabyBuf + 92, 8);
     psSHP->adBoundsMax[3] = dValue;
 
@@ -604,13 +566,15 @@ SHPHandle SHPAPI_CALL SHPOpenLL(const char *pszLayer, const char *pszAccess,
     {
         unsigned int nOffset;
         memcpy(&nOffset, pabyBuf + i * 8, 4);
-        if (!bBigEndian)
-            SwapWord(4, &nOffset);
+#if !defined(SHP_BIG_ENDIAN)
+        SHP_SWAP32(&nOffset);
+#endif
 
         unsigned int nLength;
         memcpy(&nLength, pabyBuf + i * 8 + 4, 4);
-        if (!bBigEndian)
-            SwapWord(4, &nLength);
+#if !defined(SHP_BIG_ENDIAN)
+        SHP_SWAP32(&nLength);
+#endif
 
         if (nOffset > STATIC_CAST(unsigned int, INT_MAX))
         {
@@ -691,19 +655,6 @@ int SHPAPI_CALL SHPRestoreSHX(const char *pszLayer, const char *pszAccess,
         pszAccess = "rb";
     }
 
-/* -------------------------------------------------------------------- */
-/*  Establish the byte order on this machine.                           */
-/* -------------------------------------------------------------------- */
-#if !defined(bBigEndian)
-    {
-        int i = 1;
-        if (*((unsigned char *)&i) == 1)
-            bBigEndian = false;
-        else
-            bBigEndian = true;
-    }
-#endif
-
     /* -------------------------------------------------------------------- */
     /*  Open the .shp file.  Note that files pulled from                    */
     /*  a PC to Unix with upper case filenames won't work!                  */
@@ -808,16 +759,18 @@ int SHPAPI_CALL SHPRestoreSHX(const char *pszLayer, const char *pszAccess,
             char abyReadRecord[8];
             unsigned int nRecordOffsetBE = nRecordOffset;
 
-            if (!bBigEndian)
-                SwapWord(4, &nRecordOffsetBE);
+#if !defined(SHP_BIG_ENDIAN)
+            SHP_SWAP32(&nRecordOffsetBE);
+#endif
             memcpy(abyReadRecord, &nRecordOffsetBE, 4);
             memcpy(abyReadRecord + 4, &nRecordLength, 4);
 
-            if (!bBigEndian)
-                SwapWord(4, &nRecordLength);
-
-            if (bBigEndian)
-                SwapWord(4, &nSHPType);
+#if !defined(SHP_BIG_ENDIAN)
+            SHP_SWAP32(&nRecordLength);
+#endif
+#if defined(SHP_BIG_ENDIAN)
+            SHP_SWAP32(&nSHPType);
+#endif
 
             // Sanity check on record length
             if (nRecordLength < 1 ||
@@ -828,7 +781,7 @@ int SHPAPI_CALL SHPRestoreSHX(const char *pszLayer, const char *pszAccess,
                          "Error parsing .shp to restore .shx. "
                          "Invalid record length = %u at record starting at "
                          "offset %u",
-                         nSHPType, nCurrentSHPOffset);
+                         nRecordLength, nCurrentSHPOffset);
                 psHooks->Error(szErrorMsg);
 
                 nRetCode = FALSE;
@@ -888,8 +841,10 @@ int SHPAPI_CALL SHPRestoreSHX(const char *pszLayer, const char *pszAccess,
     }
 
     nRealSHXContentSize /= 2;  // Bytes counted -> WORDs
-    if (!bBigEndian)
-        SwapWord(4, &nRealSHXContentSize);
+#if !defined(SHP_BIG_ENDIAN)
+    SHP_SWAP32(&nRealSHXContentSize);
+#endif
+
     psHooks->FSeek(fpSHX, 24, 0);
     psHooks->FWrite(&nRealSHXContentSize, 4, 1, fpSHX);
 
@@ -975,8 +930,9 @@ void SHPAPI_CALL SHPSetFastModeReadObject(SHPHandle hSHP, int bFastMode)
 /*      Fetch general information about the shape file.                 */
 /************************************************************************/
 
-void SHPAPI_CALL SHPGetInfo(SHPHandle psSHP, int *pnEntities, int *pnShapeType,
-                            double *padfMinBound, double *padfMaxBound)
+void SHPAPI_CALL SHPGetInfo(const SHPHandle psSHP, int *pnEntities,
+                            int *pnShapeType, double *padfMinBound,
+                            double *padfMaxBound)
 {
     if (psSHP == SHPLIB_NULLPTR)
         return;
@@ -1022,19 +978,6 @@ SHPHandle SHPAPI_CALL SHPCreate(const char *pszLayer, int nShapeType)
 SHPHandle SHPAPI_CALL SHPCreateLL(const char *pszLayer, int nShapeType,
                                   const SAHooks *psHooks)
 {
-/* -------------------------------------------------------------------- */
-/*      Establish the byte order on this system.                        */
-/* -------------------------------------------------------------------- */
-#if !defined(bBigEndian)
-    {
-        int i = 1;
-        if (*((unsigned char *)&i) == 1)
-            bBigEndian = false;
-        else
-            bBigEndian = true;
-    }
-#endif
-
     /* -------------------------------------------------------------------- */
     /*      Open the two files so we can write their headers.               */
     /* -------------------------------------------------------------------- */
@@ -1051,7 +994,7 @@ SHPHandle SHPAPI_CALL SHPCreateLL(const char *pszLayer, int nShapeType,
         psHooks->Error(szErrorMsg);
 
         free(pszFullname);
-        return NULL;
+        return SHPLIB_NULLPTR;
     }
 
     memcpy(pszFullname + nLenWithoutExtension, ".shx", 5);
@@ -1065,7 +1008,7 @@ SHPHandle SHPAPI_CALL SHPCreateLL(const char *pszLayer, int nShapeType,
 
         free(pszFullname);
         psHooks->FClose(fpSHP);
-        return NULL;
+        return SHPLIB_NULLPTR;
     }
 
     free(pszFullname);
@@ -1082,18 +1025,21 @@ SHPHandle SHPAPI_CALL SHPCreateLL(const char *pszLayer, int nShapeType,
 
     uint32_t i32 = 50; /* file size */
     ByteCopy(&i32, abyHeader + 24, 4);
-    if (!bBigEndian)
-        SwapWord(4, abyHeader + 24);
+#if !defined(SHP_BIG_ENDIAN)
+    SHP_SWAP32(abyHeader + 24);
+#endif
 
     i32 = 1000; /* version */
     ByteCopy(&i32, abyHeader + 28, 4);
-    if (bBigEndian)
-        SwapWord(4, abyHeader + 28);
+#if defined(SHP_BIG_ENDIAN)
+    SHP_SWAP32(abyHeader + 28);
+#endif
 
     i32 = nShapeType; /* shape type */
     ByteCopy(&i32, abyHeader + 32, 4);
-    if (bBigEndian)
-        SwapWord(4, abyHeader + 32);
+#if defined(SHP_BIG_ENDIAN)
+    SHP_SWAP32(abyHeader + 32);
+#endif
 
     double dValue = 0.0; /* set bounds */
     ByteCopy(&dValue, abyHeader + 36, 8);
@@ -1116,7 +1062,7 @@ SHPHandle SHPAPI_CALL SHPCreateLL(const char *pszLayer, int nShapeType,
         free(pszFullname);
         psHooks->FClose(fpSHP);
         psHooks->FClose(fpSHX);
-        return NULL;
+        return SHPLIB_NULLPTR;
     }
 
     /* -------------------------------------------------------------------- */
@@ -1124,8 +1070,9 @@ SHPHandle SHPAPI_CALL SHPCreateLL(const char *pszLayer, int nShapeType,
     /* -------------------------------------------------------------------- */
     i32 = 50; /* file size */
     ByteCopy(&i32, abyHeader + 24, 4);
-    if (!bBigEndian)
-        SwapWord(4, abyHeader + 24);
+#if !defined(SHP_BIG_ENDIAN)
+    SHP_SWAP32(abyHeader + 24);
+#endif
 
     if (psHooks->FWrite(abyHeader, 100, 1, fpSHX) != 1)
     {
@@ -1139,10 +1086,10 @@ SHPHandle SHPAPI_CALL SHPCreateLL(const char *pszLayer, int nShapeType,
         free(pszFullname);
         psHooks->FClose(fpSHP);
         psHooks->FClose(fpSHX);
-        return NULL;
+        return SHPLIB_NULLPTR;
     }
 
-    SHPHandle psSHP = STATIC_CAST(SHPHandle, calloc(sizeof(SHPInfo), 1));
+    SHPHandle psSHP = STATIC_CAST(SHPHandle, calloc(1, sizeof(SHPInfo)));
 
     psSHP->bUpdated = FALSE;
     memcpy(&(psSHP->sHooks), psHooks, sizeof(SAHooks));
@@ -1187,13 +1134,12 @@ static void _SHPSetBounds(unsigned char *pabyRec, const SHPObject *psShape)
     ByteCopy(&(psShape->dfXMax), pabyRec + 16, 8);
     ByteCopy(&(psShape->dfYMax), pabyRec + 24, 8);
 
-    if (bBigEndian)
-    {
-        SwapWord(8, pabyRec + 0);
-        SwapWord(8, pabyRec + 8);
-        SwapWord(8, pabyRec + 16);
-        SwapWord(8, pabyRec + 24);
-    }
+#if defined(SHP_BIG_ENDIAN)
+    SHP_SWAP64(pabyRec + 0);
+    SHP_SWAP64(pabyRec + 8);
+    SHP_SWAP64(pabyRec + 16);
+    SHP_SWAP64(pabyRec + 24);
+#endif
 }
 
 /************************************************************************/
@@ -1286,7 +1232,7 @@ SHPObject SHPAPI_CALL1(*)
         psObject->nParts = MAX(1, nParts);
 
         psObject->panPartStart =
-            STATIC_CAST(int *, calloc(sizeof(int), psObject->nParts));
+            STATIC_CAST(int *, calloc(psObject->nParts, sizeof(int)));
         psObject->panPartType =
             STATIC_CAST(int *, malloc(sizeof(int) * psObject->nParts));
 
@@ -1304,8 +1250,7 @@ SHPObject SHPAPI_CALL1(*)
                 psObject->panPartType[i] = SHPP_RING;
         }
 
-        if (psObject->panPartStart[0] != 0)
-            psObject->panPartStart[0] = 0;
+        psObject->panPartStart[0] = 0;
     }
 
     /* -------------------------------------------------------------------- */
@@ -1316,16 +1261,16 @@ SHPObject SHPAPI_CALL1(*)
         const size_t nSize = sizeof(double) * nVertices;
         psObject->padfX =
             STATIC_CAST(double *, padfX ? malloc(nSize)
-                                        : calloc(sizeof(double), nVertices));
+                                        : calloc(nVertices, sizeof(double)));
         psObject->padfY =
             STATIC_CAST(double *, padfY ? malloc(nSize)
-                                        : calloc(sizeof(double), nVertices));
+                                        : calloc(nVertices, sizeof(double)));
         psObject->padfZ = STATIC_CAST(
             double *,
-            padfZ &&bHasZ ? malloc(nSize) : calloc(sizeof(double), nVertices));
+            padfZ &&bHasZ ? malloc(nSize) : calloc(nVertices, sizeof(double)));
         psObject->padfM = STATIC_CAST(
             double *,
-            padfM &&bHasM ? malloc(nSize) : calloc(sizeof(double), nVertices));
+            padfM &&bHasM ? malloc(nSize) : calloc(nVertices, sizeof(double)));
         if (padfX != SHPLIB_NULLPTR)
             memcpy(psObject->padfX, padfX, nSize);
         if (padfY != SHPLIB_NULLPTR)
@@ -1371,7 +1316,7 @@ SHPObject SHPAPI_CALL1(*)
 /************************************************************************/
 
 int SHPAPI_CALL SHPWriteObject(SHPHandle psSHP, int nShapeId,
-                               SHPObject *psObject)
+                               const SHPObject *psObject)
 {
     psSHP->bUpdated = TRUE;
 
@@ -1472,10 +1417,10 @@ int SHPAPI_CALL SHPWriteObject(SHPHandle psSHP, int nShapeId,
 
         _SHPSetBounds(pabyRec + 12, psObject);
 
-        if (bBigEndian)
-            SwapWord(4, &nPoints);
-        if (bBigEndian)
-            SwapWord(4, &nParts);
+#if defined(SHP_BIG_ENDIAN)
+        SHP_SWAP32(&nPoints);
+        SHP_SWAP32(&nParts);
+#endif
 
         ByteCopy(&nPoints, pabyRec + 40 + 8, 4);
         ByteCopy(&nParts, pabyRec + 36 + 8, 4);
@@ -1489,8 +1434,9 @@ int SHPAPI_CALL SHPWriteObject(SHPHandle psSHP, int nShapeId,
                  4 * psObject->nParts);
         for (int i = 0; i < psObject->nParts; i++)
         {
-            if (bBigEndian)
-                SwapWord(4, pabyRec + 44 + 8 + 4 * i);
+#if defined(SHP_BIG_ENDIAN)
+            SHP_SWAP32(pabyRec + 44 + 8 + 4 * i);
+#endif
             nRecordSize += 4;
         }
 
@@ -1503,8 +1449,9 @@ int SHPAPI_CALL SHPWriteObject(SHPHandle psSHP, int nShapeId,
                    4 * psObject->nParts);
             for (int i = 0; i < psObject->nParts; i++)
             {
-                if (bBigEndian)
-                    SwapWord(4, pabyRec + nRecordSize);
+#if defined(SHP_BIG_ENDIAN)
+                SHP_SWAP32(pabyRec + nRecordSize);
+#endif
                 nRecordSize += 4;
             }
         }
@@ -1517,11 +1464,10 @@ int SHPAPI_CALL SHPWriteObject(SHPHandle psSHP, int nShapeId,
             ByteCopy(psObject->padfX + i, pabyRec + nRecordSize, 8);
             ByteCopy(psObject->padfY + i, pabyRec + nRecordSize + 8, 8);
 
-            if (bBigEndian)
-                SwapWord(8, pabyRec + nRecordSize);
-
-            if (bBigEndian)
-                SwapWord(8, pabyRec + nRecordSize + 8);
+#if defined(SHP_BIG_ENDIAN)
+            SHP_SWAP64(pabyRec + nRecordSize);
+            SHP_SWAP64(pabyRec + nRecordSize + 8);
+#endif
 
             nRecordSize += 2 * 8;
         }
@@ -1534,20 +1480,23 @@ int SHPAPI_CALL SHPWriteObject(SHPHandle psSHP, int nShapeId,
             psObject->nSHPType == SHPT_MULTIPATCH)
         {
             ByteCopy(&(psObject->dfZMin), pabyRec + nRecordSize, 8);
-            if (bBigEndian)
-                SwapWord(8, pabyRec + nRecordSize);
+#if defined(SHP_BIG_ENDIAN)
+            SHP_SWAP64(pabyRec + nRecordSize);
+#endif
             nRecordSize += 8;
 
             ByteCopy(&(psObject->dfZMax), pabyRec + nRecordSize, 8);
-            if (bBigEndian)
-                SwapWord(8, pabyRec + nRecordSize);
+#if defined(SHP_BIG_ENDIAN)
+            SHP_SWAP64(pabyRec + nRecordSize);
+#endif
             nRecordSize += 8;
 
             for (int i = 0; i < psObject->nVertices; i++)
             {
                 ByteCopy(psObject->padfZ + i, pabyRec + nRecordSize, 8);
-                if (bBigEndian)
-                    SwapWord(8, pabyRec + nRecordSize);
+#if defined(SHP_BIG_ENDIAN)
+                SHP_SWAP64(pabyRec + nRecordSize);
+#endif
                 nRecordSize += 8;
             }
         }
@@ -1565,20 +1514,23 @@ int SHPAPI_CALL SHPWriteObject(SHPHandle psSHP, int nShapeId,
              psObject->nSHPType == SHPT_ARCZ))
         {
             ByteCopy(&(psObject->dfMMin), pabyRec + nRecordSize, 8);
-            if (bBigEndian)
-                SwapWord(8, pabyRec + nRecordSize);
+#if defined(SHP_BIG_ENDIAN)
+            SHP_SWAP64(pabyRec + nRecordSize);
+#endif
             nRecordSize += 8;
 
             ByteCopy(&(psObject->dfMMax), pabyRec + nRecordSize, 8);
-            if (bBigEndian)
-                SwapWord(8, pabyRec + nRecordSize);
+#if defined(SHP_BIG_ENDIAN)
+            SHP_SWAP64(pabyRec + nRecordSize);
+#endif
             nRecordSize += 8;
 
             for (int i = 0; i < psObject->nVertices; i++)
             {
                 ByteCopy(psObject->padfM + i, pabyRec + nRecordSize, 8);
-                if (bBigEndian)
-                    SwapWord(8, pabyRec + nRecordSize);
+#if defined(SHP_BIG_ENDIAN)
+                SHP_SWAP64(pabyRec + nRecordSize);
+#endif
                 nRecordSize += 8;
             }
         }
@@ -1595,8 +1547,9 @@ int SHPAPI_CALL SHPWriteObject(SHPHandle psSHP, int nShapeId,
 
         _SHPSetBounds(pabyRec + 12, psObject);
 
-        if (bBigEndian)
-            SwapWord(4, &nPoints);
+#if defined(SHP_BIG_ENDIAN)
+        SHP_SWAP32(&nPoints);
+#endif
         ByteCopy(&nPoints, pabyRec + 44, 4);
 
         for (int i = 0; i < psObject->nVertices; i++)
@@ -1604,10 +1557,10 @@ int SHPAPI_CALL SHPWriteObject(SHPHandle psSHP, int nShapeId,
             ByteCopy(psObject->padfX + i, pabyRec + 48 + i * 16, 8);
             ByteCopy(psObject->padfY + i, pabyRec + 48 + i * 16 + 8, 8);
 
-            if (bBigEndian)
-                SwapWord(8, pabyRec + 48 + i * 16);
-            if (bBigEndian)
-                SwapWord(8, pabyRec + 48 + i * 16 + 8);
+#if defined(SHP_BIG_ENDIAN)
+            SHP_SWAP64(pabyRec + 48 + i * 16);
+            SHP_SWAP64(pabyRec + 48 + i * 16 + 8);
+#endif
         }
 
         nRecordSize = 48 + 16 * psObject->nVertices;
@@ -1615,20 +1568,23 @@ int SHPAPI_CALL SHPWriteObject(SHPHandle psSHP, int nShapeId,
         if (psObject->nSHPType == SHPT_MULTIPOINTZ)
         {
             ByteCopy(&(psObject->dfZMin), pabyRec + nRecordSize, 8);
-            if (bBigEndian)
-                SwapWord(8, pabyRec + nRecordSize);
+#if defined(SHP_BIG_ENDIAN)
+            SHP_SWAP64(pabyRec + nRecordSize);
+#endif
             nRecordSize += 8;
 
             ByteCopy(&(psObject->dfZMax), pabyRec + nRecordSize, 8);
-            if (bBigEndian)
-                SwapWord(8, pabyRec + nRecordSize);
+#if defined(SHP_BIG_ENDIAN)
+            SHP_SWAP64(pabyRec + nRecordSize);
+#endif
             nRecordSize += 8;
 
             for (int i = 0; i < psObject->nVertices; i++)
             {
                 ByteCopy(psObject->padfZ + i, pabyRec + nRecordSize, 8);
-                if (bBigEndian)
-                    SwapWord(8, pabyRec + nRecordSize);
+#if defined(SHP_BIG_ENDIAN)
+                SHP_SWAP64(pabyRec + nRecordSize);
+#endif
                 nRecordSize += 8;
             }
         }
@@ -1638,20 +1594,23 @@ int SHPAPI_CALL SHPWriteObject(SHPHandle psSHP, int nShapeId,
              psObject->nSHPType == SHPT_MULTIPOINTM))
         {
             ByteCopy(&(psObject->dfMMin), pabyRec + nRecordSize, 8);
-            if (bBigEndian)
-                SwapWord(8, pabyRec + nRecordSize);
+#if defined(SHP_BIG_ENDIAN)
+            SHP_SWAP64(pabyRec + nRecordSize);
+#endif
             nRecordSize += 8;
 
             ByteCopy(&(psObject->dfMMax), pabyRec + nRecordSize, 8);
-            if (bBigEndian)
-                SwapWord(8, pabyRec + nRecordSize);
+#if defined(SHP_BIG_ENDIAN)
+            SHP_SWAP64(pabyRec + nRecordSize);
+#endif
             nRecordSize += 8;
 
             for (int i = 0; i < psObject->nVertices; i++)
             {
                 ByteCopy(psObject->padfM + i, pabyRec + nRecordSize, 8);
-                if (bBigEndian)
-                    SwapWord(8, pabyRec + nRecordSize);
+#if defined(SHP_BIG_ENDIAN)
+                SHP_SWAP64(pabyRec + nRecordSize);
+#endif
                 nRecordSize += 8;
             }
         }
@@ -1667,18 +1626,19 @@ int SHPAPI_CALL SHPWriteObject(SHPHandle psSHP, int nShapeId,
         ByteCopy(psObject->padfX, pabyRec + 12, 8);
         ByteCopy(psObject->padfY, pabyRec + 20, 8);
 
-        if (bBigEndian)
-            SwapWord(8, pabyRec + 12);
-        if (bBigEndian)
-            SwapWord(8, pabyRec + 20);
+#if defined(SHP_BIG_ENDIAN)
+        SHP_SWAP64(pabyRec + 12);
+        SHP_SWAP64(pabyRec + 20);
+#endif
 
         nRecordSize = 28;
 
         if (psObject->nSHPType == SHPT_POINTZ)
         {
             ByteCopy(psObject->padfZ, pabyRec + nRecordSize, 8);
-            if (bBigEndian)
-                SwapWord(8, pabyRec + nRecordSize);
+#if defined(SHP_BIG_ENDIAN)
+            SHP_SWAP64(pabyRec + nRecordSize);
+#endif
             nRecordSize += 8;
         }
 
@@ -1686,8 +1646,9 @@ int SHPAPI_CALL SHPWriteObject(SHPHandle psSHP, int nShapeId,
                                          psObject->nSHPType == SHPT_POINTM))
         {
             ByteCopy(psObject->padfM, pabyRec + nRecordSize, 8);
-            if (bBigEndian)
-                SwapWord(8, pabyRec + nRecordSize);
+#if defined(SHP_BIG_ENDIAN)
+            SHP_SWAP64(pabyRec + nRecordSize);
+#endif
             nRecordSize += 8;
         }
     }
@@ -1751,18 +1712,21 @@ int SHPAPI_CALL SHPWriteObject(SHPHandle psSHP, int nShapeId,
     /* -------------------------------------------------------------------- */
     uint32_t i32 =
         (nShapeId < 0) ? psSHP->nRecords + 1 : nShapeId + 1; /* record # */
-    if (!bBigEndian)
-        SwapWord(4, &i32);
+#if !defined(SHP_BIG_ENDIAN)
+    SHP_SWAP32(&i32);
+#endif
     ByteCopy(&i32, pabyRec, 4);
 
     i32 = (nRecordSize - 8) / 2; /* record size */
-    if (!bBigEndian)
-        SwapWord(4, &i32);
+#if !defined(SHP_BIG_ENDIAN)
+    SHP_SWAP32(&i32);
+#endif
     ByteCopy(&i32, pabyRec + 4, 4);
 
     i32 = psObject->nSHPType; /* shape type */
-    if (bBigEndian)
-        SwapWord(4, &i32);
+#if defined(SHP_BIG_ENDIAN)
+    SHP_SWAP32(&i32);
+#endif
     ByteCopy(&i32, pabyRec + 8, 4);
 
     /* -------------------------------------------------------------------- */
@@ -1924,7 +1888,7 @@ static unsigned char *SHPReallocObjectBufIfNecessary(SHPHandle psSHP,
 /*      for one shape.                                                  */
 /************************************************************************/
 
-SHPObject SHPAPI_CALL1(*) SHPReadObject(SHPHandle psSHP, int hEntity)
+SHPObject SHPAPI_CALL1(*) SHPReadObject(const SHPHandle psSHP, int hEntity)
 {
     /* -------------------------------------------------------------------- */
     /*      Validate the record/entity number.                              */
@@ -1954,10 +1918,10 @@ SHPObject SHPAPI_CALL1(*) SHPReadObject(SHPHandle psSHP, int hEntity)
             psSHP->sHooks.Error(str);
             return SHPLIB_NULLPTR;
         }
-        if (!bBigEndian)
-            SwapWord(4, &nOffset);
-        if (!bBigEndian)
-            SwapWord(4, &nLength);
+#if !defined(SHP_BIG_ENDIAN)
+        SHP_SWAP32(&nOffset);
+        SHP_SWAP32(&nLength);
+#endif
 
         if (nOffset > STATIC_CAST(unsigned int, INT_MAX))
         {
@@ -2089,8 +2053,9 @@ SHPObject SHPAPI_CALL1(*) SHPReadObject(SHPHandle psSHP, int hEntity)
         /* Do a sanity check */
         int nSHPContentLength;
         memcpy(&nSHPContentLength, psSHP->pabyRec + 4, 4);
-        if (!bBigEndian)
-            SwapWord(4, &(nSHPContentLength));
+#if !defined(SHP_BIG_ENDIAN)
+        SHP_SWAP32(&(nSHPContentLength));
+#endif
         if (nSHPContentLength < 0 || nSHPContentLength > INT_MAX / 2 - 4 ||
             2 * nSHPContentLength + 8 != nBytesRead)
         {
@@ -2135,8 +2100,9 @@ SHPObject SHPAPI_CALL1(*) SHPReadObject(SHPHandle psSHP, int hEntity)
     int nSHPType;
     memcpy(&nSHPType, psSHP->pabyRec + 8, 4);
 
-    if (bBigEndian)
-        SwapWord(4, &(nSHPType));
+#if defined(SHP_BIG_ENDIAN)
+    SHP_SWAP32(&(nSHPType));
+#endif
 
     /* -------------------------------------------------------------------- */
     /*      Allocate and minimally initialize the object.                   */
@@ -2185,19 +2151,17 @@ SHPObject SHPAPI_CALL1(*) SHPReadObject(SHPHandle psSHP, int hEntity)
         /* -------------------------------------------------------------------- */
         /*      Get the X/Y bounds.                                             */
         /* -------------------------------------------------------------------- */
-        memcpy(&(psShape->dfXMin), psSHP->pabyRec + 8 + 4, 8);
-        memcpy(&(psShape->dfYMin), psSHP->pabyRec + 8 + 12, 8);
-        memcpy(&(psShape->dfXMax), psSHP->pabyRec + 8 + 20, 8);
-        memcpy(&(psShape->dfYMax), psSHP->pabyRec + 8 + 28, 8);
-
-        if (bBigEndian)
-            SwapWord(8, &(psShape->dfXMin));
-        if (bBigEndian)
-            SwapWord(8, &(psShape->dfYMin));
-        if (bBigEndian)
-            SwapWord(8, &(psShape->dfXMax));
-        if (bBigEndian)
-            SwapWord(8, &(psShape->dfYMax));
+#if defined(SHP_BIG_ENDIAN)
+        SHP_SWAPDOUBLE_CPY(&psShape->dfXMin, psSHP->pabyRec + 8 + 4);
+        SHP_SWAPDOUBLE_CPY(&psShape->dfYMin, psSHP->pabyRec + 8 + 12);
+        SHP_SWAPDOUBLE_CPY(&psShape->dfXMax, psSHP->pabyRec + 8 + 20);
+        SHP_SWAPDOUBLE_CPY(&psShape->dfYMax, psSHP->pabyRec + 8 + 28);
+#else
+        memcpy(&psShape->dfXMin, psSHP->pabyRec + 8 + 4, 8);
+        memcpy(&psShape->dfYMin, psSHP->pabyRec + 8 + 12, 8);
+        memcpy(&psShape->dfXMax, psSHP->pabyRec + 8 + 20, 8);
+        memcpy(&psShape->dfYMax, psSHP->pabyRec + 8 + 28, 8);
+#endif
 
         /* -------------------------------------------------------------------- */
         /*      Extract part/point count, and build vertex and part arrays      */
@@ -2208,10 +2172,10 @@ SHPObject SHPAPI_CALL1(*) SHPReadObject(SHPHandle psSHP, int hEntity)
         uint32_t nParts;
         memcpy(&nParts, psSHP->pabyRec + 36 + 8, 4);
 
-        if (bBigEndian)
-            SwapWord(4, &nPoints);
-        if (bBigEndian)
-            SwapWord(4, &nParts);
+#if defined(SHP_BIG_ENDIAN)
+        SHP_SWAP32(&nPoints);
+        SHP_SWAP32(&nParts);
+#endif
 
         /* nPoints and nParts are unsigned */
         if (/* nPoints < 0 || nParts < 0 || */
@@ -2309,8 +2273,9 @@ SHPObject SHPAPI_CALL1(*) SHPReadObject(SHPHandle psSHP, int hEntity)
         memcpy(psShape->panPartStart, psSHP->pabyRec + 44 + 8, 4 * nParts);
         for (int i = 0; STATIC_CAST(uint32_t, i) < nParts; i++)
         {
-            if (bBigEndian)
-                SwapWord(4, psShape->panPartStart + i);
+#if defined(SHP_BIG_ENDIAN)
+            SHP_SWAP32(psShape->panPartStart + i);
+#endif
 
             /* We check that the offset is inside the vertex array */
             if (psShape->panPartStart[i] < 0 ||
@@ -2355,8 +2320,9 @@ SHPObject SHPAPI_CALL1(*) SHPReadObject(SHPHandle psSHP, int hEntity)
             memcpy(psShape->panPartType, psSHP->pabyRec + nOffset, 4 * nParts);
             for (int i = 0; STATIC_CAST(uint32_t, i) < nParts; i++)
             {
-                if (bBigEndian)
-                    SwapWord(4, psShape->panPartType + i);
+#if defined(SHP_BIG_ENDIAN)
+                SHP_SWAP32(psShape->panPartType + i);
+#endif
             }
 
             nOffset += 4 * nParts;
@@ -2367,15 +2333,16 @@ SHPObject SHPAPI_CALL1(*) SHPReadObject(SHPHandle psSHP, int hEntity)
         /* -------------------------------------------------------------------- */
         for (int i = 0; STATIC_CAST(uint32_t, i) < nPoints; i++)
         {
+#if defined(SHP_BIG_ENDIAN)
+            SHP_SWAPDOUBLE_CPY(psShape->padfX + i,
+                               psSHP->pabyRec + nOffset + i * 16);
+            SHP_SWAPDOUBLE_CPY(psShape->padfY + i,
+                               psSHP->pabyRec + nOffset + i * 16 + 8);
+#else
             memcpy(psShape->padfX + i, psSHP->pabyRec + nOffset + i * 16, 8);
-
             memcpy(psShape->padfY + i, psSHP->pabyRec + nOffset + i * 16 + 8,
                    8);
-
-            if (bBigEndian)
-                SwapWord(8, psShape->padfX + i);
-            if (bBigEndian)
-                SwapWord(8, psShape->padfY + i);
+#endif
         }
 
         nOffset += 16 * nPoints;
@@ -2387,20 +2354,24 @@ SHPObject SHPAPI_CALL1(*) SHPReadObject(SHPHandle psSHP, int hEntity)
             psShape->nSHPType == SHPT_ARCZ ||
             psShape->nSHPType == SHPT_MULTIPATCH)
         {
-            memcpy(&(psShape->dfZMin), psSHP->pabyRec + nOffset, 8);
-            memcpy(&(psShape->dfZMax), psSHP->pabyRec + nOffset + 8, 8);
+#if defined(SHP_BIG_ENDIAN)
+            SHP_SWAPDOUBLE_CPY(&psShape->dfZMin, psSHP->pabyRec + nOffset);
+            SHP_SWAPDOUBLE_CPY(&psShape->dfZMax, psSHP->pabyRec + nOffset + 8);
+#else
+            memcpy(&psShape->dfZMin, psSHP->pabyRec + nOffset, 8);
+            memcpy(&psShape->dfZMax, psSHP->pabyRec + nOffset + 8, 8);
 
-            if (bBigEndian)
-                SwapWord(8, &(psShape->dfZMin));
-            if (bBigEndian)
-                SwapWord(8, &(psShape->dfZMax));
+#endif
 
             for (int i = 0; STATIC_CAST(uint32_t, i) < nPoints; i++)
             {
+#if defined(SHP_BIG_ENDIAN)
+                SHP_SWAPDOUBLE_CPY(psShape->padfZ + i,
+                                   psSHP->pabyRec + nOffset + 16 + i * 8);
+#else
                 memcpy(psShape->padfZ + i,
                        psSHP->pabyRec + nOffset + 16 + i * 8, 8);
-                if (bBigEndian)
-                    SwapWord(8, psShape->padfZ + i);
+#endif
             }
 
             nOffset += 16 + 8 * nPoints;
@@ -2418,20 +2389,23 @@ SHPObject SHPAPI_CALL1(*) SHPReadObject(SHPHandle psSHP, int hEntity)
         /* -------------------------------------------------------------------- */
         if (nEntitySize >= STATIC_CAST(int, nOffset + 16 + 8 * nPoints))
         {
-            memcpy(&(psShape->dfMMin), psSHP->pabyRec + nOffset, 8);
-            memcpy(&(psShape->dfMMax), psSHP->pabyRec + nOffset + 8, 8);
-
-            if (bBigEndian)
-                SwapWord(8, &(psShape->dfMMin));
-            if (bBigEndian)
-                SwapWord(8, &(psShape->dfMMax));
+#if defined(SHP_BIG_ENDIAN)
+            SHP_SWAPDOUBLE_CPY(&psShape->dfMMin, psSHP->pabyRec + nOffset);
+            SHP_SWAPDOUBLE_CPY(&psShape->dfMMax, psSHP->pabyRec + nOffset + 8);
+#else
+            memcpy(&psShape->dfMMin, psSHP->pabyRec + nOffset, 8);
+            memcpy(&psShape->dfMMax, psSHP->pabyRec + nOffset + 8, 8);
+#endif
 
             for (int i = 0; STATIC_CAST(uint32_t, i) < nPoints; i++)
             {
+#if defined(SHP_BIG_ENDIAN)
+                SHP_SWAPDOUBLE_CPY(psShape->padfM + i,
+                                   psSHP->pabyRec + nOffset + 16 + i * 8);
+#else
                 memcpy(psShape->padfM + i,
                        psSHP->pabyRec + nOffset + 16 + i * 8, 8);
-                if (bBigEndian)
-                    SwapWord(8, psShape->padfM + i);
+#endif
             }
             psShape->bMeasureIsUsed = TRUE;
         }
@@ -2462,8 +2436,9 @@ SHPObject SHPAPI_CALL1(*) SHPReadObject(SHPHandle psSHP, int hEntity)
         uint32_t nPoints;
         memcpy(&nPoints, psSHP->pabyRec + 44, 4);
 
-        if (bBigEndian)
-            SwapWord(4, &nPoints);
+#if defined(SHP_BIG_ENDIAN)
+        SHP_SWAP32(&nPoints);
+#endif
 
         /* nPoints is unsigned */
         if (/* nPoints < 0 || */ nPoints > 50 * 1000 * 1000)
@@ -2536,13 +2511,15 @@ SHPObject SHPAPI_CALL1(*) SHPReadObject(SHPHandle psSHP, int hEntity)
 
         for (int i = 0; STATIC_CAST(uint32_t, i) < nPoints; i++)
         {
+#if defined(SHP_BIG_ENDIAN)
+            SHP_SWAPDOUBLE_CPY(psShape->padfX + i,
+                               psSHP->pabyRec + 48 + 16 * i);
+            SHP_SWAPDOUBLE_CPY(psShape->padfY + i,
+                               psSHP->pabyRec + 48 + 16 * i + 8);
+#else
             memcpy(psShape->padfX + i, psSHP->pabyRec + 48 + 16 * i, 8);
             memcpy(psShape->padfY + i, psSHP->pabyRec + 48 + 16 * i + 8, 8);
-
-            if (bBigEndian)
-                SwapWord(8, psShape->padfX + i);
-            if (bBigEndian)
-                SwapWord(8, psShape->padfY + i);
+#endif
         }
 
         int nOffset = 48 + 16 * nPoints;
@@ -2550,39 +2527,40 @@ SHPObject SHPAPI_CALL1(*) SHPReadObject(SHPHandle psSHP, int hEntity)
         /* -------------------------------------------------------------------- */
         /*      Get the X/Y bounds.                                             */
         /* -------------------------------------------------------------------- */
-        memcpy(&(psShape->dfXMin), psSHP->pabyRec + 8 + 4, 8);
-        memcpy(&(psShape->dfYMin), psSHP->pabyRec + 8 + 12, 8);
-        memcpy(&(psShape->dfXMax), psSHP->pabyRec + 8 + 20, 8);
-        memcpy(&(psShape->dfYMax), psSHP->pabyRec + 8 + 28, 8);
-
-        if (bBigEndian)
-            SwapWord(8, &(psShape->dfXMin));
-        if (bBigEndian)
-            SwapWord(8, &(psShape->dfYMin));
-        if (bBigEndian)
-            SwapWord(8, &(psShape->dfXMax));
-        if (bBigEndian)
-            SwapWord(8, &(psShape->dfYMax));
+#if defined(SHP_BIG_ENDIAN)
+        SHP_SWAPDOUBLE_CPY(&psShape->dfXMin, psSHP->pabyRec + 8 + 4);
+        SHP_SWAPDOUBLE_CPY(&psShape->dfYMin, psSHP->pabyRec + 8 + 12);
+        SHP_SWAPDOUBLE_CPY(&psShape->dfXMax, psSHP->pabyRec + 8 + 20);
+        SHP_SWAPDOUBLE_CPY(&psShape->dfYMax, psSHP->pabyRec + 8 + 28);
+#else
+        memcpy(&psShape->dfXMin, psSHP->pabyRec + 8 + 4, 8);
+        memcpy(&psShape->dfYMin, psSHP->pabyRec + 8 + 12, 8);
+        memcpy(&psShape->dfXMax, psSHP->pabyRec + 8 + 20, 8);
+        memcpy(&psShape->dfYMax, psSHP->pabyRec + 8 + 28, 8);
+#endif
 
         /* -------------------------------------------------------------------- */
         /*      If we have a Z coordinate, collect that now.                    */
         /* -------------------------------------------------------------------- */
         if (psShape->nSHPType == SHPT_MULTIPOINTZ)
         {
-            memcpy(&(psShape->dfZMin), psSHP->pabyRec + nOffset, 8);
-            memcpy(&(psShape->dfZMax), psSHP->pabyRec + nOffset + 8, 8);
-
-            if (bBigEndian)
-                SwapWord(8, &(psShape->dfZMin));
-            if (bBigEndian)
-                SwapWord(8, &(psShape->dfZMax));
+#if defined(SHP_BIG_ENDIAN)
+            SHP_SWAPDOUBLE_CPY(&psShape->dfZMin, psSHP->pabyRec + nOffset);
+            SHP_SWAPDOUBLE_CPY(&psShape->dfZMax, psSHP->pabyRec + nOffset + 8);
+#else
+            memcpy(&psShape->dfZMin, psSHP->pabyRec + nOffset, 8);
+            memcpy(&psShape->dfZMax, psSHP->pabyRec + nOffset + 8, 8);
+#endif
 
             for (int i = 0; STATIC_CAST(uint32_t, i) < nPoints; i++)
             {
+#if defined(SHP_BIG_ENDIAN)
+                SHP_SWAPDOUBLE_CPY(psShape->padfZ + i,
+                                   psSHP->pabyRec + nOffset + 16 + i * 8);
+#else
                 memcpy(psShape->padfZ + i,
                        psSHP->pabyRec + nOffset + 16 + i * 8, 8);
-                if (bBigEndian)
-                    SwapWord(8, psShape->padfZ + i);
+#endif
             }
 
             nOffset += 16 + 8 * nPoints;
@@ -2598,20 +2576,23 @@ SHPObject SHPAPI_CALL1(*) SHPReadObject(SHPHandle psSHP, int hEntity)
         /* -------------------------------------------------------------------- */
         if (nEntitySize >= STATIC_CAST(int, nOffset + 16 + 8 * nPoints))
         {
-            memcpy(&(psShape->dfMMin), psSHP->pabyRec + nOffset, 8);
-            memcpy(&(psShape->dfMMax), psSHP->pabyRec + nOffset + 8, 8);
-
-            if (bBigEndian)
-                SwapWord(8, &(psShape->dfMMin));
-            if (bBigEndian)
-                SwapWord(8, &(psShape->dfMMax));
+#if defined(SHP_BIG_ENDIAN)
+            SHP_SWAPDOUBLE_CPY(&psShape->dfMMin, psSHP->pabyRec + nOffset);
+            SHP_SWAPDOUBLE_CPY(&psShape->dfMMax, psSHP->pabyRec + nOffset + 8);
+#else
+            memcpy(&psShape->dfMMin, psSHP->pabyRec + nOffset, 8);
+            memcpy(&psShape->dfMMax, psSHP->pabyRec + nOffset + 8, 8);
+#endif
 
             for (int i = 0; STATIC_CAST(uint32_t, i) < nPoints; i++)
             {
+#if defined(SHP_BIG_ENDIAN)
+                SHP_SWAPDOUBLE_CPY(psShape->padfM + i,
+                                   psSHP->pabyRec + nOffset + 16 + i * 8);
+#else
                 memcpy(psShape->padfM + i,
                        psSHP->pabyRec + nOffset + 16 + i * 8, 8);
-                if (bBigEndian)
-                    SwapWord(8, psShape->padfM + i);
+#endif
             }
             psShape->bMeasureIsUsed = TRUE;
         }
@@ -2655,13 +2636,13 @@ SHPObject SHPAPI_CALL1(*) SHPReadObject(SHPHandle psSHP, int hEntity)
             SHPDestroyObject(psShape);
             return SHPLIB_NULLPTR;
         }
+#if defined(SHP_BIG_ENDIAN)
+        SHP_SWAPDOUBLE_CPY(psShape->padfX, psSHP->pabyRec + 12);
+        SHP_SWAPDOUBLE_CPY(psShape->padfY, psSHP->pabyRec + 20);
+#else
         memcpy(psShape->padfX, psSHP->pabyRec + 12, 8);
         memcpy(psShape->padfY, psSHP->pabyRec + 20, 8);
-
-        if (bBigEndian)
-            SwapWord(8, psShape->padfX);
-        if (bBigEndian)
-            SwapWord(8, psShape->padfY);
+#endif
 
         int nOffset = 20 + 8;
 
@@ -2670,10 +2651,11 @@ SHPObject SHPAPI_CALL1(*) SHPReadObject(SHPHandle psSHP, int hEntity)
         /* -------------------------------------------------------------------- */
         if (psShape->nSHPType == SHPT_POINTZ)
         {
+#if defined(SHP_BIG_ENDIAN)
+            SHP_SWAPDOUBLE_CPY(psShape->padfZ, psSHP->pabyRec + nOffset);
+#else
             memcpy(psShape->padfZ, psSHP->pabyRec + nOffset, 8);
-
-            if (bBigEndian)
-                SwapWord(8, psShape->padfZ);
+#endif
 
             nOffset += 8;
         }
@@ -2686,10 +2668,11 @@ SHPObject SHPAPI_CALL1(*) SHPReadObject(SHPHandle psSHP, int hEntity)
         /* -------------------------------------------------------------------- */
         if (nEntitySize >= nOffset + 8)
         {
+#if defined(SHP_BIG_ENDIAN)
+            SHP_SWAPDOUBLE_CPY(psShape->padfM, psSHP->pabyRec + nOffset);
+#else
             memcpy(psShape->padfM, psSHP->pabyRec + nOffset, 8);
-
-            if (bBigEndian)
-                SwapWord(8, psShape->padfM);
+#endif
             psShape->bMeasureIsUsed = TRUE;
         }
 
@@ -2936,8 +2919,9 @@ static int SHPRewindIsInnerRing(const SHPObject *psObject, int iOpRing,
 /*      specification.                                                  */
 /************************************************************************/
 
-int SHPAPI_CALL SHPRewindObject(CPL_UNUSED SHPHandle hSHP, SHPObject *psObject)
+int SHPAPI_CALL SHPRewindObject(const SHPHandle hSHP, SHPObject *psObject)
 {
+    (void)hSHP;
     /* -------------------------------------------------------------------- */
     /*      Do nothing if this is not a polygon object.                     */
     /* -------------------------------------------------------------------- */